<!doctype html>
<html lang="cs">
<head>
  <meta charset="utf-8" />
  <meta name="viewport" content="width=device-width,initial-scale=1,viewport-fit=cover" />
  <title>Barevná paleta</title>
<link rel="manifest" href="manifest.webmanifest">
<meta name="theme-color" content="#1b1b1b">
<link rel="apple-touch-icon" href="pwa/icon-192x192.png">
<meta name="apple-mobile-web-app-capable" content="yes">
<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent">


  <style>
    :root{
      color-scheme: dark;
      --bg: #1b1b1b;
      --panel: #232323;
      --text:#e6e6e6;
      --muted:#b5b5b5;
      --shadow: 0 10px 30px rgba(0,0,0,.45);
      --r-lg: 18px;
      --gap: 10px;

      --dockH: 94px; /* JS will keep this synced with actual dock height */
    }
    *{ box-sizing:border-box; }
    body{
      margin:0;
      font-family: system-ui, -apple-system, Segoe UI, Roboto, Arial;
      background: var(--bg);
      color: var(--text);
    }

    /* Header */
    .topbar{
      position: sticky;
      top: 0;
      z-index: 30;
      padding: 12px 14px calc(10px + env(safe-area-inset-top)) 14px;
      background: linear-gradient(to bottom, rgba(27,27,27,.95), rgba(27,27,27,.78));
      backdrop-filter: blur(10px);
      border-bottom: 1px solid rgba(255,255,255,.06);
    }
    .toprow{
      display:flex;
      align-items:center;
      justify-content:space-between;
      gap:10px;
    }
    .title{
      font-size: 15px;
      font-weight: 650;
      letter-spacing:.2px;
      margin:0;
      white-space:nowrap;
      overflow:hidden;
      text-overflow:ellipsis;
    }
    .btnrow{ display:flex; gap:8px; }
    .iconbtn{
      border:1px solid rgba(255,255,255,.10);
      background: rgba(255,255,255,.06);
      color: var(--text);
      border-radius: 12px;
      padding: 8px 10px;
      line-height: 1;
      display:flex;
      align-items:center;
      gap:8px;
      cursor:pointer;
      user-select:none;
      -webkit-tap-highlight-color: transparent;
    }
    .iconbtn:active{ transform: translateY(1px); }

    /* Tabs */
    .tabs{
      display:flex;
      gap:8px;
      margin-top:10px;
    }
    .tab{
      flex:1;
      border:1px solid rgba(255,255,255,.10);
      background: rgba(255,255,255,.05);
      color: var(--muted);
      padding:10px 10px;
      border-radius: 14px;
      font-size: 13px;
      font-weight: 600;
      cursor:pointer;
      text-align:center;
      user-select:none;
      -webkit-tap-highlight-color: transparent;
    }
    .tab.active{
      background: rgba(255,255,255,.10);
      color: var(--text);
      border-color: rgba(255,255,255,.18);
    }

    /* Content */
    .content{
      padding: 12px 12px calc(var(--dockH) + 18px + env(safe-area-inset-bottom)) 12px;
      max-width: 1180px;
      margin: 0 auto;
    }

    /* Picker list */
    .section{
      margin: 12px 0 14px;
      display:none;
    }
    .section.active{ display:block; }

    .pillgrid{
      display:grid;
      grid-template-columns: repeat(2, minmax(0, 1fr));
      gap:10px;
    }
    @media (min-width: 480px){
      .pillgrid{ grid-template-columns: repeat(3, minmax(0, 1fr)); }
    }
    @media (min-width: 820px){
      .pillgrid{ grid-template-columns: repeat(4, minmax(0, 1fr)); }
    }
    .pill{
      background: var(--panel);
      border: 1px solid rgba(255,255,255,.08);
      border-radius: 16px;
      padding: 12px 12px;
      cursor:pointer;
      display:flex;
      align-items:center;
      justify-content:space-between;
      gap:10px;
      box-shadow: 0 1px 0 rgba(255,255,255,.03) inset;
      -webkit-tap-highlight-color: transparent;
    }
    .pill:active{ transform: translateY(1px); }
    .pill span{
      font-size: 14px;
      font-weight: 650;
      color: var(--text);
    }
    .pill small{
      color: var(--muted);
      font-weight:600;
      opacity:.85;
    }

    /* Harmony separator */
    .harmonySep{
      margin: 4px 0 0;
      padding: 12px 12px;
      border-radius: 16px;
      background: rgba(255,255,255,.05);
      border: 1px solid rgba(255,255,255,.08);
    }
    .harmonySep h3{
      margin:0 0 6px;
      font-size: 13px;
      letter-spacing:.2px;
      color: var(--text);
    }
    .harmonySep p{
      margin:0;
      font-size: 13px;
      line-height: 1.35;
      color: var(--muted);
    }
    .harmonySep strong{ color: var(--text); }

    /* Grid */
    .grid{
      display:grid;
      gap: var(--gap);
      grid-template-columns: repeat(2, minmax(0, 1fr));
      -webkit-tap-highlight-color: transparent;
    }
    .grid.cols-1{ grid-template-columns: 1fr; }
    .grid.cols-2{ grid-template-columns: repeat(2, minmax(0, 1fr)); }
    .grid.cols-3{ grid-template-columns: repeat(3, minmax(0, 1fr)); }
    .grid.cols-4{ grid-template-columns: repeat(4, minmax(0, 1fr)); }

    @media (min-width: 900px){
      .grid.cols-4{ grid-template-columns: repeat(5, minmax(0, 1fr)); }
    }

    .card{
      background: var(--panel);
      border: 1px solid rgba(255,255,255,.07);
      border-radius: var(--r-lg);
      overflow:hidden;
      cursor:pointer;
      box-shadow: 0 1px 0 rgba(255,255,255,.03) inset;
      position:relative;
      -webkit-tap-highlight-color: transparent;
    }
    .card:active{ transform: translateY(1px); }

    /* Harmony cards */
    .card.harmony{
      border-color: rgba(255,255,255,.14);
      box-shadow: 0 1px 0 rgba(255,255,255,.05) inset;
    }
    .badge{
      position:absolute;
      top:10px;
      left:10px;
      font-size: 10.5px;
      font-weight: 800;
      letter-spacing: .08em;
      padding: 6px 8px;
      border-radius: 999px;
      background: rgba(0,0,0,.32);
      border: 1px solid rgba(255,255,255,.14);
      color: rgba(255,255,255,.88);
      backdrop-filter: blur(6px);
    }

    .thumb{
      width:100%;
      height:auto;
      display:block;
      aspect-ratio: 3/4;
      object-fit: cover;
      background: linear-gradient(135deg, #2a2a2a, #1f1f1f);
    }
    .skeleton{
      position:absolute;
      inset:0;
      background: linear-gradient(90deg, rgba(255,255,255,.06), rgba(255,255,255,.02), rgba(255,255,255,.06));
      background-size: 200% 100%;
      animation: shimmer 1.1s infinite linear;
      opacity:.55;
    }
    .card.loaded .skeleton{ display:none; }
    @keyframes shimmer{
      0%{ background-position: 200% 0; }
      100%{ background-position: -200% 0; }
    }

    /* Lightbox */
    .lb{
      position: fixed;
      inset: 0;
      z-index: 80;
      display:none;
      align-items:center;
      justify-content:center;
      padding: 16px;
      background: rgba(0,0,0,.86);
      backdrop-filter: blur(6px);
    }
    .lb.open{ display:flex; }
    .lbwrap{
      width: min(980px, 96vw);
      height: min(92vh, 980px);
      display:flex;
      flex-direction: column;
      align-items:center;
      justify-content:center;
      position:relative;
      gap: 10px;
    }
    .lbimg{
      max-width: 100%;
      max-height: calc(100% - 60px);
      border-radius: 18px;
      box-shadow: var(--shadow);
      background: #111;
    }
    .lbclose{
      position:absolute;
      top: 0;
      right: 0;
      transform: translate(6px, -6px);
      border:1px solid rgba(255,255,255,.14);
      background: rgba(255,255,255,.08);
      color: var(--text);
      border-radius: 14px;
      padding: 10px 12px;
      cursor:pointer;
      font-weight:700;
      user-select:none;
      -webkit-tap-highlight-color: transparent;
    }
    .lbarrow{
      position:absolute;
      top: 50%;
      transform: translateY(-50%);
      border:1px solid rgba(255,255,255,.14);
      background: rgba(255,255,255,.08);
      color: var(--text);
      border-radius: 14px;
      padding: 10px 12px;
      cursor:pointer;
      font-weight:800;
      user-select:none;
      display:none;
      -webkit-tap-highlight-color: transparent;
    }
    .lbarrow.left{ left: 0; transform: translate(-6px,-50%); }
    .lbarrow.right{ right: 0; transform: translate(6px,-50%); }
    @media (min-width: 900px){
      .lbarrow{ display:block; }
    }

    .lbActions{
      display:flex;
      gap:10px;
      align-items:center;
      justify-content:center;
      width: 100%;
      padding-bottom: env(safe-area-inset-bottom);
    }
    .lbBtn{
      border:1px solid rgba(255,255,255,.14);
      background: rgba(255,255,255,.08);
      color: var(--text);
      border-radius: 14px;
      padding: 10px 12px;
      cursor:pointer;
      font-weight: 750;
      user-select:none;
      -webkit-tap-highlight-color: transparent;
    }
    .lbBtn.primary{
      border-color: rgba(255,255,255,.18);
      background: rgba(255,255,255,.12);
    }
    .lbBtn:active{ transform: translateY(1px); }

    /* Info toast */
    .info{
      position: fixed;
      left: 12px;
      right: 12px;
      bottom: calc(var(--dockH) + 12px);
      z-index: 60;
      background: rgba(35,35,35,.92);
      border: 1px solid rgba(255,255,255,.10);
      border-radius: 16px;
      padding: 12px 12px;
      display:none;
      box-shadow: var(--shadow);
    }
    .info.open{ display:block; }
    .info .row{ display:flex; justify-content:space-between; gap:10px; align-items:flex-start; }
    .info p{ margin:0; color: var(--muted); font-size: 13px; line-height: 1.35; }
    .info button{ border:none; background:transparent; color: var(--text); font-weight:800; cursor:pointer; }

    /* Bottom palette dock */
    .dock{
      position: fixed;
      left: 10px;
      right: 10px;
      bottom: calc(10px + env(safe-area-inset-bottom));
      z-index: 65;
      background: rgba(35,35,35,.92);
      border: 1px solid rgba(255,255,255,.10);
      border-radius: 18px;
      box-shadow: var(--shadow);
      backdrop-filter: blur(10px);
      padding: 10px;
    }
    .dockTop{
      display:flex;
      align-items:center;
      justify-content:space-between;
      gap:10px;
      margin-bottom: 8px;
    }
    .dockTitle{
      font-size: 13px;
      font-weight: 800;
      letter-spacing: .02em;
      color: var(--text);
      display:flex;
      align-items:center;
      gap:8px;
      white-space:nowrap;
      overflow:hidden;
      text-overflow:ellipsis;
    }
    .dockTitle small{
      color: var(--muted);
      font-weight: 700;
    }
    .dockBtns{
      display:flex;
      gap:8px;
      align-items:center;
      flex-shrink:0;
      flex-wrap: wrap;
      justify-content:flex-end;
    }
    .dockBtn{
      border:1px solid rgba(255,255,255,.14);
      background: rgba(255,255,255,.08);
      color: var(--text);
      border-radius: 14px;
      padding: 8px 10px;
      cursor:pointer;
      font-weight: 750;
      user-select:none;
      -webkit-tap-highlight-color: transparent;
      font-size: 12.5px;
      line-height: 1;
    }
    .dockBtn:disabled{
      opacity: .45;
      cursor: not-allowed;
    }
    .dockBtn:active{ transform: translateY(1px); }

    .slots{
      display:grid;
      grid-template-columns: repeat(5, minmax(0, 1fr));
      gap: 8px;
    }
    .slot{
      position:relative;
      border-radius: 14px;
      border: 1px dashed rgba(255,255,255,.18);
      background: rgba(255,255,255,.04);
      overflow:hidden;
      aspect-ratio: 3/4;
      cursor:pointer;
      -webkit-tap-highlight-color: transparent;
      display:flex;
      align-items:center;
      justify-content:center;
      color: rgba(255,255,255,.6);
      font-weight: 900;
      font-size: 18px;
      user-select:none;
    }
    .slot.filled{
      border-style: solid;
      border-color: rgba(255,255,255,.14);
      background: rgba(0,0,0,.18);
    }
    .slot img{
      width:100%;
      height:100%;
      object-fit: cover;
      display:block;
    }
    .slotX{
      position:absolute;
      top:6px;
      right:6px;
      width: 26px;
      height: 26px;
      border-radius: 999px;
      display:flex;
      align-items:center;
      justify-content:center;
      font-weight: 900;
      font-size: 14px;
      background: rgba(0,0,0,.40);
      border: 1px solid rgba(255,255,255,.14);
      color: rgba(255,255,255,.9);
      backdrop-filter: blur(6px);
      pointer-events:none;
    }

    /* Moodboard view (expanded) */
    .moodboard{
      display:none;
      gap:10px;
      overflow-x: auto;
      padding-bottom: 2px;
      scroll-snap-type: x mandatory;
      -webkit-overflow-scrolling: touch;
    }
    .moodItem{
      flex: 0 0 auto;
      width: 150px;
      aspect-ratio: 3/4;
      border-radius: 16px;
      overflow:hidden;
      border: 1px solid rgba(255,255,255,.14);
      background: rgba(0,0,0,.18);
      position:relative;
      cursor:pointer;
      scroll-snap-align: start;
      -webkit-tap-highlight-color: transparent;
    }
    .moodItem img{ width:100%; height:100%; object-fit: cover; display:block; }
    .moodX{
      position:absolute;
      top:8px;
      right:8px;
      width: 30px;
      height: 30px;
      border-radius: 999px;
      display:flex;
      align-items:center;
      justify-content:center;
      font-weight: 900;
      font-size: 16px;
      background: rgba(0,0,0,.45);
      border: 1px solid rgba(255,255,255,.16);
      color: rgba(255,255,255,.92);
      backdrop-filter: blur(6px);
      pointer-events:none;
    }
    .dock.expanded .slots{ display:none; }
    .dock.expanded .moodboard{ display:flex; }

    @media (min-width: 900px){
      .dock{ left: 14px; right: 14px; }
      .slots{ grid-template-columns: repeat(5, 88px); justify-content:flex-start; }
      .moodItem{ width: 180px; }
    }
  </style>
</head>

<body>
  <header class="topbar" id="topbar">
    <div class="toprow">
      <h1 class="title" id="pageTitle">Barevná paleta</h1>
      <div class="btnrow">
        <button class="iconbtn" id="gridBtn" type="button">▦ <span style="font-weight:650;" id="gridBtnLabel">Mřížka 2×</span></button>
        <button class="iconbtn" id="infoBtn" type="button">ℹ️ <span style="font-weight:650;">Info</span></button>
      </div>
    </div>
    <div class="tabs" role="tablist">
      <div class="tab active" id="tabSeasons" role="tab">Sezóny</div>
      <div class="tab" id="tabTypes" role="tab">12 typů</div>
      <div class="tab" id="tabColors" role="tab">Barvy</div>
    </div>
  </header>

  <main class="content">
    <section class="section active" id="secSeasons"></section>
    <section class="section" id="secTypes"></section>
    <section class="section" id="secColors"></section>

    <div id="harmonyBlock"></div>
    <div class="grid" id="grid"></div>
  </main>

  <!-- Lightbox -->
  <div class="lb" id="lb" aria-modal="true" role="dialog">
    <div class="lbwrap">
      <button class="lbclose" id="lbClose" type="button">✕</button>
      <div class="lbarrow left" id="lbPrev">‹</div>
      <img class="lbimg" id="lbImg" alt="">
      <div class="lbarrow right" id="lbNext">›</div>

      <div class="lbActions">
        <button class="lbBtn primary" id="lbAddBtn" type="button">Přidat do palety</button>
      </div>
    </div>
  </div>

  <!-- Info toast -->
  <div class="info" id="info">
    <div class="row">
      <p id="disclaimerText"></p>
      <button id="infoClose" type="button">✕</button>
    </div>
  </div>

  <!-- Bottom palette dock -->
  <div class="dock" id="dock">
    <div class="dockTop">
      <div class="dockTitle">
        Paleta <small id="dockCount">(0/5)</small>
      </div>
      <div class="dockBtns">
        <button class="dockBtn" id="dockSize" type="button" title="Změnit velikost palety (zmenšit / zvětšit)">Velikost</button>
        <button class="dockBtn" id="dockClear" type="button" title="Vymazat paletu">Vymazat</button>
        <button class="dockBtn" id="dockShare" type="button" title="Sdílet PNG">Sdílet</button>
        <button class="dockBtn" id="dockExport" type="button" title="Stáhnout PNG (průhledné pozadí)">Export PNG</button>
      </div>
    </div>

    <div class="moodboard" id="moodboard"></div>
    <div class="slots" id="slots"></div>
  </div>

<script>
(async function(){
  const $ = (id) => document.getElementById(id);

  const config = await fetch("data/app.config.json", {cache:"no-store"}).then(r=>r.json());
  const harmoniesRaw = await fetch("data/harmonies.json", {cache:"no-store"}).then(r=>r.json());
  const manifest = await fetch("data/manifest.json", {cache:"no-store"}).then(r=>r.json());

  const harmonies = Array.isArray(harmoniesRaw)
    ? Object.fromEntries(harmoniesRaw.map(x => [x.id, x.harmonies || []]))
    : harmoniesRaw;

  function getHarmony(typeId){
    return harmonies[typeId]
      || harmonies[typeId.replaceAll("-", "_")]
      || harmonies[typeId.replaceAll("_", "-")]
      || [];
  }

  $("disclaimerText").textContent = config.ui?.disclaimer || "";

  const grid = $("grid");
  const harmonyBlock = $("harmonyBlock");
  const pageTitle = $("pageTitle");
  const gridBtnLabel = $("gridBtnLabel");

  function scrollToTop(smooth=true){
    window.scrollTo({ top: 0, behavior: smooth ? "smooth" : "auto" });
  }

  // Tabs
  const tabs = [
    { tab: $("tabSeasons"), sec: $("secSeasons") },
    { tab: $("tabTypes"), sec: $("secTypes") },
    { tab: $("tabColors"), sec: $("secColors") }
  ];
  function setTab(i, {scrollUp=false} = {}){
    tabs.forEach((t, idx)=>{
      t.tab.classList.toggle("active", idx===i);
      t.sec.classList.toggle("active", idx===i);
    });
    if (scrollUp) scrollToTop(true);
  }
  tabs[0].tab.onclick = ()=> setTab(0, {scrollUp:true});
  tabs[1].tab.onclick = ()=> setTab(1, {scrollUp:true});
  tabs[2].tab.onclick = ()=> setTab(2, {scrollUp:true});

  // Maps
  const typeById = Object.fromEntries(config.types.map(t => [t.id, t]));
  const seasonById = Object.fromEntries(config.seasons.map(s => [s.id, s]));
  const colorById = Object.fromEntries(config.byColor.map(c => [c.id, c]));

  // Scroll memory per view key
  let currentViewKey = null;
  function saveScroll(){
    if (!currentViewKey) return;
    try { sessionStorage.setItem("scroll:" + currentViewKey, String(window.scrollY || 0)); } catch(e){}
  }
  function restoreScroll(){
    if (!currentViewKey) return false;
    try{
      const v = sessionStorage.getItem("scroll:" + currentViewKey);
      if (v === null) return false;
      const y = parseInt(v, 10);
      if (!Number.isFinite(y)) return false;
      window.scrollTo({ top: y, behavior:"auto" });
      return true;
    } catch(e){ return false; }
  }
  function setViewKey(key){
    saveScroll();
    currentViewKey = key;
  }
  window.addEventListener("scroll", ()=>{ saveScroll(); }, {passive:true});

  // Grid columns (1..4)
  let cols = parseInt(localStorage.getItem("palette_cols") || "2", 10);
  if (![1,2,3,4].includes(cols)) cols = 2;

  function applyCols(){
    grid.classList.remove("cols-1","cols-2","cols-3","cols-4");
    grid.classList.add("cols-" + cols);
    localStorage.setItem("palette_cols", String(cols));
    gridBtnLabel.textContent = "Mřížka " + cols + "×";
  }
  applyCols();

  $("gridBtn").onclick = ()=>{
    cols = cols % 4 + 1;
    applyCols();
  };

  // Swipe on grid to change columns
  let startX=null, startY=null;
  grid.addEventListener("touchstart", (e)=>{
    if (e.touches.length !== 1) return;
    startX = e.touches[0].clientX;
    startY = e.touches[0].clientY;
  }, {passive:true});

  grid.addEventListener("touchend", (e)=>{
    if (startX===null || startY===null) return;
    const endX = e.changedTouches[0].clientX;
    const endY = e.changedTouches[0].clientY;
    const dx = endX - startX;
    const dy = endY - startY;

    startX = startY = null;

    if (Math.abs(dx) < 50) return;
    if (Math.abs(dx) < Math.abs(dy) * 1.2) return;

    if (dx > 0) cols = Math.max(1, cols - 1);
    else cols = Math.min(4, cols + 1);

    applyCols();
  }, {passive:true});

  // Info toast
  const info = $("info");
  $("infoBtn").onclick = ()=> info.classList.add("open");
  $("infoClose").onclick = ()=> info.classList.remove("open");

  // Lightbox
  const lb = $("lb");
  const lbImg = $("lbImg");
  const lbAddBtn = $("lbAddBtn");
  let currentList = [];
  let currentIndex = 0;

  function currentPath(){
    return currentList?.[currentIndex] || null;
  }

  function openLightbox(list, idx){
    currentList = list;
    currentIndex = idx;
    lbImg.src = list[idx];
    lb.classList.add("open");
    updateLbAddBtn();
  }
  function closeLightbox(){ lb.classList.remove("open"); }
  function prev(){
    if(!currentList.length) return;
    currentIndex = (currentIndex - 1 + currentList.length) % currentList.length;
    lbImg.src = currentList[currentIndex];
    updateLbAddBtn();
  }
  function next(){
    if(!currentList.length) return;
    currentIndex = (currentIndex + 1) % currentList.length;
    lbImg.src = currentList[currentIndex];
    updateLbAddBtn();
  }

  $("lbClose").onclick = closeLightbox;
  $("lbPrev").onclick = prev;
  $("lbNext").onclick = next;
  lb.addEventListener("click", (e)=> { if(e.target === lb) closeLightbox(); });
  document.addEventListener("keydown", (e)=>{
    if(!lb.classList.contains("open")) return;
    if(e.key === "Escape") closeLightbox();
    if(e.key === "ArrowLeft") prev();
    if(e.key === "ArrowRight") next();
  });

  let lbTouchX = null;
  lb.addEventListener("touchstart", (e)=>{ lbTouchX = e.touches[0].clientX; }, {passive:true});
  lb.addEventListener("touchend", (e)=>{
    if(lbTouchX === null) return;
    const dx = e.changedTouches[0].clientX - lbTouchX;
    lbTouchX = null;
    if(Math.abs(dx) < 35) return;
    dx > 0 ? prev() : next();
  }, {passive:true});

  // --- Palette dock (5) ---
  const dock = $("dock");
  const slotsEl = $("slots");
  const moodboardEl = $("moodboard");
  const dockCount = $("dockCount");
  const dockExport = $("dockExport");
  const dockShare = $("dockShare");
  const dockClear = $("dockClear");
  const dockSize = $("dockSize");

  let picked = [];
  try {
    picked = JSON.parse(localStorage.getItem("picked_palette") || "[]");
    if (!Array.isArray(picked)) picked = [];
  } catch(e){ picked = []; }
  picked = picked.filter(Boolean).slice(0,5);

  let dockExpanded = (localStorage.getItem("dock_expanded") || "0") === "1";
  if (dockExpanded) dock.classList.add("expanded");

  function savePicked(){
    try { localStorage.setItem("picked_palette", JSON.stringify(picked)); } catch(e){}
  }
  function isPicked(path){
    return picked.includes(path);
  }
  function addPicked(path){
    if (!path) return;
    if (isPicked(path)) return;
    if (picked.length >= 5) return;
    picked.push(path);
    savePicked();
    renderDock();
    updateLbAddBtn();
  }
  function removePicked(path){
    picked = picked.filter(p => p !== path);
    savePicked();
    renderDock();
    updateLbAddBtn();
  }

  function updateDockHeightVar(){
    const h = dock.getBoundingClientRect().height;
    document.documentElement.style.setProperty("--dockH", Math.ceil(h) + "px");
  }

  // Only show "Sdílet" if device can share FILES
  function supportsFileShare(){
    try{
      if (!navigator.share || !navigator.canShare) return false;
      const testFile = new File([new Blob(["x"], {type:"image/png"})], "test.png", {type:"image/png"});
      return navigator.canShare({ files: [testFile] });
    } catch(e){
      return false;
    }
  }
  const fileShareOk = supportsFileShare();
  if (!fileShareOk) {
    dockShare.style.display = "none"; // hide completely
  }

  function renderDock(){
    dockCount.textContent = `(${picked.length}/5)`;
    dockExport.disabled = picked.length === 0;
    dockClear.disabled = picked.length === 0;

    // Sdílet: když je podporované, jen disable při prázdné paletě
    if (fileShareOk) dockShare.disabled = picked.length === 0;

    // compact slots
    slotsEl.innerHTML = "";
    for (let i=0; i<5; i++){
      const slot = document.createElement("div");
      const path = picked[i] || null;
      slot.className = "slot" + (path ? " filled" : "");
      if (!path) {
        slot.textContent = "+";
        slot.title = "Přidej barvu přes detail (Přidat do palety)";
      } else {
        const img = document.createElement("img");
        img.src = path;
        img.loading = "lazy";
        slot.appendChild(img);

        const x = document.createElement("div");
        x.className = "slotX";
        x.textContent = "×";
        slot.appendChild(x);

        slot.title = "Klikni pro odebrání";
      }
      slot.onclick = ()=>{ if (path) removePicked(path); };
      slotsEl.appendChild(slot);
    }

    // moodboard (expanded)
    moodboardEl.innerHTML = "";
    picked.forEach((path)=>{
      const it = document.createElement("div");
      it.className = "moodItem";
      const img = document.createElement("img");
      img.src = path;
      img.loading = "lazy";
      it.appendChild(img);

      const x = document.createElement("div");
      x.className = "moodX";
      x.textContent = "×";
      it.appendChild(x);

      it.title = "Klikni pro odebrání";
      it.onclick = ()=> removePicked(path);
      moodboardEl.appendChild(it);
    });

    updateDockHeightVar();
  }

  function updateLbAddBtn(){
    const p = currentPath();
    if (!p){
      lbAddBtn.disabled = true;
      lbAddBtn.textContent = "Přidat do palety";
      return;
    }
    lbAddBtn.disabled = false;

    if (isPicked(p)){
      lbAddBtn.textContent = "Odebrat z palety";
      lbAddBtn.classList.remove("primary");
    } else {
      lbAddBtn.textContent = picked.length >= 5 ? "Paleta je plná (5)" : "Přidat do palety";
      lbAddBtn.classList.add("primary");
      lbAddBtn.disabled = picked.length >= 5;
    }
  }

  lbAddBtn.onclick = ()=>{
    const p = currentPath();
    if (!p) return;
    if (isPicked(p)) removePicked(p);
    else addPicked(p);
  };

  dockClear.onclick = ()=>{
    picked = [];
    savePicked();
    renderDock();
    updateLbAddBtn();
  };

  dockSize.onclick = ()=>{
    dockExpanded = !dockExpanded;
    dock.classList.toggle("expanded", dockExpanded);
    try { localStorage.setItem("dock_expanded", dockExpanded ? "1" : "0"); } catch(e){}
    renderDock();
  };

  async function loadImage(path){
    return new Promise((resolve, reject)=>{
      const img = new Image();
      img.onload = ()=> resolve(img);
      img.onerror = ()=> reject(new Error("Nelze načíst obrázek: " + path));
      img.src = path;
    });
  }

  async function buildPalettePngDataUrl(){
    const imgs = [];
    for (const p of picked){
      imgs.push(await loadImage(p));
    }

    // output sizing (3:4)
    const outH = 1200;
    const outW = Math.round(outH * 3/4);
    const gap = 0;

    const canvas = document.createElement("canvas");
    canvas.width = imgs.length * outW + (imgs.length - 1) * gap;
    canvas.height = outH;

    const ctx = canvas.getContext("2d");
    // transparent bg => do NOT fill

    imgs.forEach((img, i)=>{
      const x = i * (outW + gap);
      const iw = img.naturalWidth || img.width;
      const ih = img.naturalHeight || img.height;

      // cover scaling
      const scale = Math.max(outW / iw, outH / ih);
      const sw = outW / scale;
      const sh = outH / scale;
      const sx = (iw - sw) / 2;
      const sy = (ih - sh) / 2;

      ctx.drawImage(img, sx, sy, sw, sh, x, 0, outW, outH);
    });

    return canvas.toDataURL("image/png");
  }

  dockExport.onclick = async ()=>{
    try{
      const dataUrl = await buildPalettePngDataUrl();
      const a = document.createElement("a");
      a.href = dataUrl;
      a.download = "paleta.png";
      document.body.appendChild(a);
      a.click();
      a.remove();
    } catch(err){
      alert("Export se nepodařil: " + (err?.message || err));
    }
  };

  if (fileShareOk){
    dockShare.onclick = async ()=>{
      try{
        const dataUrl = await buildPalettePngDataUrl();
        const blob = await (await fetch(dataUrl)).blob();
        const file = new File([blob], "paleta.png", { type: "image/png" });

        if (navigator.canShare && navigator.canShare({ files: [file] })){
          await navigator.share({
            title: "Paleta",
            text: "Barevná paleta",
            files: [file]
          });
          return;
        }

        // If something unexpected happens, fallback:
        window.open(dataUrl, "_blank");
      } catch(err){
        alert("Sdílení se nepodařilo: " + (err?.message || err));
      }
    };
  }

  // Keep CSS var in sync (resize/orientation)
  window.addEventListener("resize", ()=> updateDockHeightVar(), {passive:true});
  setTimeout(()=> updateDockHeightVar(), 0);

  renderDock();

  // --- Rendering ---
  function renderGridInto(targetGrid, paths, isHarmony=false){
    const list = paths || [];
    list.forEach((p, idx)=>{
      const card = document.createElement("div");
      card.className = "card" + (isHarmony ? " harmony" : "");

      const sk = document.createElement("div");
      sk.className = "skeleton";

      const img = document.createElement("img");
      img.className = "thumb";
      img.loading = "lazy";
      img.src = p;

      img.addEventListener("load", async ()=>{
        card.classList.add("loaded");
        try { await img.decode(); } catch(e){}
      });

      card.appendChild(sk);

      if (isHarmony){
        const b = document.createElement("div");
        b.className = "badge";
        b.textContent = "HARMONIE";
        card.appendChild(b);
      }

      card.appendChild(img);
      card.onclick = ()=> openLightbox(list, idx);
      targetGrid.appendChild(card);
    });
  }

  function renderGrid(paths){
    grid.innerHTML = "";
    renderGridInto(grid, paths, false);
  }

  function openType(typeId){
    const key = "type:" + typeId;
    setViewKey(key);

    const typeLabel = typeById[typeId]?.label || typeId;
    pageTitle.textContent = typeLabel;

    const base = manifest.types[typeId] || [];
    const related = getHarmony(typeId);
    const relatedLabels = related.map(id => typeById[id]?.label || id);

    const relatedPaths = [];
    related.forEach(id=>{
      (manifest.types[id] || []).forEach(p => relatedPaths.push(p));
    });

    grid.innerHTML = "";
    harmonyBlock.innerHTML = "";

    renderGridInto(grid, base, false);

    if (related.length){
      const sep = document.createElement("div");
      sep.className = "harmonySep";

      const h = document.createElement("h3");
      h.textContent = "Harmonické kombinace";

      const p = document.createElement("p");
      p.innerHTML = `<strong>${typeLabel}</strong> můžete harmonicky kombinovat také s barvami z: <strong>${relatedLabels.join(", ")}</strong>.`;

      sep.appendChild(h);
      sep.appendChild(p);

      sep.style.gridColumn = "1 / -1";
      grid.appendChild(sep);

      renderGridInto(grid, relatedPaths, true);
    }

    const restored = restoreScroll();
    if (!restored) scrollToTop(true);
  }

  function openSeason(seasonId){
    const key = "season:" + seasonId;
    setViewKey(key);

    pageTitle.textContent = seasonById[seasonId]?.label || seasonId;
    harmonyBlock.innerHTML = "";

    const all = [];
    (seasonById[seasonId]?.types || []).forEach(tid=>{
      (manifest.types[tid] || []).forEach(p=> all.push(p));
    });

    renderGrid(all);

    const restored = restoreScroll();
    if (!restored) scrollToTop(true);
  }

  function openByColor(colorId){
    const key = "color:" + colorId;
    setViewKey(key);

    pageTitle.textContent = colorById[colorId]?.label || colorId;
    harmonyBlock.innerHTML = "";

    renderGrid(manifest.byColor[colorId] || []);

    const restored = restoreScroll();
    if (!restored) scrollToTop(true);
  }

  function buildPills(container, items, onClick, rightLabel){
    container.innerHTML = `<div class="pillgrid"></div>`;
    const pg = container.querySelector(".pillgrid");
    items.forEach(it=>{
      const btn = document.createElement("div");
      btn.className = "pill";

      const left = document.createElement("span");
      left.textContent = it.label;

      const right = document.createElement("small");
      right.textContent = rightLabel || "";

      btn.appendChild(left);
      btn.appendChild(right);
      btn.onclick = ()=> onClick(it.id);

      pg.appendChild(btn);
    });
  }

  buildPills($("secSeasons"), config.seasons, (id)=>{ setTab(0); openSeason(id); }, "90");
  buildPills($("secTypes"), config.types, (id)=>{ setTab(1); openType(id); }, "30");
  buildPills($("secColors"), config.byColor, (id)=>{ setTab(2); openByColor(id); }, "");

  // Start
  setTab(0);
  openSeason("jaro");
})();
</script>
</body>
</html>
