{"id":235945,"date":"2026-10-29T16:00:32","date_gmt":"2026-10-29T15:00:32","guid":{"rendered":"https:\/\/viallidesign.com\/?page_id=235945"},"modified":"2026-10-30T09:33:40","modified_gmt":"2026-10-30T08:33:40","slug":"katalog","status":"publish","type":"page","link":"https:\/\/viallidesign.com\/en\/katalog\/","title":{"rendered":"Catalogue"},"content":{"rendered":"<!-- === POCZ\u0104TEK WIDGETU KATALOGU VIALLI DESIGN 2026 (FULLSCREEN + ZOOM + MOBILE) === -->\n<div id=\"moj-flipbook-widget\">\n  <style>\n    #moj-flipbook-widget {\n      width: 100%;\n      max-width: 1440px;\n      margin: 15px auto;\n      background-color: #ffffff;\n      border: 1px solid #eaeaea;\n      border-radius: 16px;\n      display: flex;\n      flex-direction: column;\n      box-shadow: 0 10px 35px rgba(0, 0, 0, 0.06);\n      font-family: system-ui, -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, sans-serif;\n      box-sizing: border-box;\n      overflow: hidden;\n      user-select: none;\n    }\n\n    \/* Tryb pe\u0142noekranowy - maksymalne wykorzystanie przestrzeni *\/\n    #moj-flipbook-widget:fullscreen,\n    #moj-flipbook-widget:-webkit-full-screen {\n      background-color: #ffffff;\n      max-width: 100vw;\n      width: 100vw;\n      height: 100vh;\n      margin: 0;\n      border-radius: 0;\n      border: none;\n    }\n\n    \/* --- G\u00d3RNY PASEK NARZ\u0118DZIOWY (POWY\u017bEJ KATALOGU) --- *\/\n    #moj-flipbook-widget .fb-header-bar {\n      width: 100%;\n      background-color: #ffffff;\n      border-bottom: 1px solid #f0f0f2;\n      padding: 10px 20px;\n      display: flex;\n      flex-wrap: wrap;\n      justify-content: space-between;\n      align-items: center;\n      gap: 12px;\n      box-sizing: border-box;\n      z-index: 40;\n      flex-shrink: 0;\n    }\n\n    \/* Prze\u0142\u0105cznik j\u0119zyk\u00f3w *\/\n    #moj-flipbook-widget .fb-lang-switcher {\n      display: inline-flex;\n      background: #f4f4f6;\n      padding: 4px;\n      border-radius: 30px;\n      border: 1px solid #e4e4e7;\n      gap: 4px;\n    }\n\n    #moj-flipbook-widget .fb-lang-btn {\n      background: transparent;\n      color: #52525b;\n      border: none;\n      padding: 6px 16px;\n      border-radius: 25px;\n      font-size: 0.8rem;\n      font-weight: 600;\n      letter-spacing: 0.5px;\n      cursor: pointer;\n      transition: all 0.2s ease;\n    }\n\n    #moj-flipbook-widget .fb-lang-btn:hover {\n      color: #18181b;\n      background: rgba(0, 0, 0, 0.04);\n    }\n\n    #moj-flipbook-widget .fb-lang-btn.active {\n      background: #18181b;\n      color: #ffffff;\n      box-shadow: 0 2px 6px rgba(0, 0, 0, 0.15);\n    }\n\n    \/* Nawigacja, Zoom i Pobieranie *\/\n    #moj-flipbook-widget .fb-controls-group {\n      display: flex;\n      flex-wrap: wrap;\n      justify-content: center;\n      gap: 8px;\n      align-items: center;\n      transition: opacity 0.2s ease;\n    }\n\n    #moj-flipbook-widget .fb-controls-group.is-disabled {\n      opacity: 0.4;\n      pointer-events: none;\n    }\n\n    #moj-flipbook-widget .fb-pill {\n      display: inline-flex;\n      align-items: center;\n      gap: 6px;\n      background: #f4f4f6;\n      border: 1px solid #e4e4e7;\n      padding: 4px 8px;\n      border-radius: 30px;\n    }\n\n    #moj-flipbook-widget .fb-btn {\n      padding: 6px 13px;\n      background: #18181b;\n      color: #ffffff;\n      border: none;\n      border-radius: 20px;\n      cursor: pointer;\n      font-size: 0.78rem;\n      font-weight: 600;\n      text-decoration: none;\n      display: inline-flex;\n      align-items: center;\n      justify-content: center;\n      gap: 5px;\n      transition: background 0.2s, transform 0.1s;\n      line-height: 1.2;\n      white-space: nowrap;\n    }\n\n    #moj-flipbook-widget .fb-btn:hover {\n      background: #3f3f46;\n    }\n\n    #moj-flipbook-widget .fb-btn:active {\n      transform: scale(0.95);\n    }\n\n    #moj-flipbook-widget .fb-btn-icon {\n      padding: 6px 10px;\n      min-width: 32px;\n      font-size: 0.85rem;\n    }\n\n    #moj-flipbook-widget .fb-btn-secondary {\n      background: #ffffff;\n      color: #18181b;\n      border: 1px solid #d4d4d8;\n    }\n\n    #moj-flipbook-widget .fb-btn-secondary:hover {\n      background: #e4e4e7;\n    }\n\n    #moj-flipbook-widget .fb-counter,\n    #moj-flipbook-widget .fb-zoom-label {\n      font-size: 0.82rem;\n      font-weight: 600;\n      color: #27272a;\n      text-align: center;\n      font-variant-numeric: tabular-nums;\n      padding: 0 6px;\n    }\n\n    #moj-flipbook-widget .fb-counter {\n      min-width: 90px;\n    }\n\n    #moj-flipbook-widget .fb-zoom-label {\n      min-width: 44px;\n      cursor: pointer;\n    }\n\n    \/* --- G\u0141\u00d3WNA SCENA KATALOGU (DU\u017bA PRZESTRZE\u0143) --- *\/\n    #moj-flipbook-widget .fb-stage {\n      position: relative;\n      width: 100%;\n      \/* Na PC zajmuje 84% wysoko\u015bci okna przegl\u0105darki - strony s\u0105 wyra\u017anie wi\u0119ksze *\/\n      height: 84vh;\n      min-height: 620px;\n      max-height: 980px;\n      background-color: #ffffff;\n      display: flex;\n      justify-content: center;\n      align-items: center;\n      padding: 12px 16px;\n      box-sizing: border-box;\n      overflow: hidden;\n    }\n\n    \/* Na pe\u0142nym ekranie zdejmujemy wszelkie limity wysoko\u015bci *\/\n    #moj-flipbook-widget:fullscreen .fb-stage,\n    #moj-flipbook-widget:-webkit-full-screen .fb-stage {\n      flex: 1;\n      height: calc(100vh - 62px);\n      max-height: none;\n      min-height: 0;\n      padding: 10px;\n    }\n\n    \/* Kontener przesuwania i przybli\u017cania (Zoom & Pan) *\/\n    #moj-flipbook-widget .fb-zoom-layer {\n      width: 100%;\n      height: 100%;\n      display: flex;\n      justify-content: center;\n      align-items: center;\n      transform-origin: center center;\n      transition: transform 0.18s ease-out;\n    }\n\n    #moj-flipbook-widget .fb-zoom-layer.is-zoomed {\n      cursor: grab;\n    }\n\n    #moj-flipbook-widget .fb-zoom-layer.is-dragging {\n      cursor: grabbing;\n      transition: none;\n    }\n\n    \/* Pasek \u0142adowania na \u015brodku sceny *\/\n    #moj-flipbook-widget .fb-loader {\n      position: absolute;\n      top: 50%;\n      left: 50%;\n      transform: translate(-50%, -50%);\n      width: 320px;\n      max-width: 85%;\n      background: #ffffff;\n      border: 1px solid #e4e4e7;\n      box-shadow: 0 12px 30px rgba(0, 0, 0, 0.08);\n      padding: 22px 26px;\n      border-radius: 16px;\n      z-index: 30;\n      text-align: center;\n    }\n\n    #moj-flipbook-widget .fb-loader-text {\n      font-size: 0.92rem;\n      font-weight: 600;\n      color: #18181b;\n      margin-bottom: 12px;\n      font-variant-numeric: tabular-nums;\n    }\n\n    #moj-flipbook-widget .fb-progress-track {\n      width: 100%;\n      height: 8px;\n      background: #f4f4f5;\n      border-radius: 10px;\n      overflow: hidden;\n    }\n\n    #moj-flipbook-widget .fb-progress-bar {\n      width: 0%;\n      height: 100%;\n      background: #18181b;\n      border-radius: 10px;\n      transition: width 0.15s ease-out;\n    }\n\n    \/* Obszar samej ksi\u0105\u017cki *\/\n    #moj-flipbook-widget .fb-viewport {\n      display: flex;\n      justify-content: center;\n      align-items: center;\n      width: 100%;\n      height: 100%;\n      position: relative;\n      filter: drop-shadow(0 10px 25px rgba(0, 0, 0, 0.11));\n      opacity: 0;\n      visibility: hidden;\n      transition: opacity 0.3s ease;\n    }\n\n    #moj-flipbook-widget .fb-viewport.is-ready {\n      opacity: 1;\n      visibility: visible;\n    }\n\n    #moj-flipbook-widget .fb-page {\n      background-color: #ffffff;\n      box-shadow: inset 0 0 12px rgba(0, 0, 0, 0.04);\n      border: 1px solid #ececec;\n      display: flex;\n      justify-content: center;\n      align-items: center;\n      overflow: hidden;\n    }\n\n    #moj-flipbook-widget .fb-page canvas {\n      width: 100%;\n      height: 100%;\n      object-fit: contain;\n    }\n\n    \/* --- OPTYMALIZACJA POD TELEFON (MAKSYMALNE WYPE\u0141NIENIE EKRANU) --- *\/\n    @media (max-width: 768px) {\n      #moj-flipbook-widget {\n        margin: 5px auto;\n        border-radius: 10px;\n      }\n      #moj-flipbook-widget .fb-header-bar {\n        justify-content: center;\n        padding: 8px;\n        gap: 6px;\n      }\n      #moj-flipbook-widget .fb-lang-btn {\n        padding: 5px 12px;\n        font-size: 0.75rem;\n      }\n      #moj-flipbook-widget .fb-btn {\n        padding: 5px 10px;\n        font-size: 0.72rem;\n      }\n      #moj-flipbook-widget .fb-counter {\n        min-width: 75px;\n        font-size: 0.75rem;\n      }\n      #moj-flipbook-widget .fb-stage {\n        height: 78vh;\n        min-height: 480px;\n        padding: 4px; \/* Minimalny margines na telefonie, \u017ceby strona zajmowa\u0142a ca\u0142y ekran *\/\n      }\n      #moj-flipbook-widget .hide-mobile-text {\n        display: none;\n      }\n    }\n  <\/style>\n\n  <!-- G\u00d3RNY PASEK NARZ\u0118DZIOWY (POWY\u017bEJ KATALOGU) -->\n  <div class=\"fb-header-bar\">\n    <!-- 1. Prze\u0142\u0105cznik j\u0119zyk\u00f3w -->\n    <div class=\"fb-lang-switcher\">\n      <button class=\"fb-lang-btn active\" data-lang=\"PL_EN\">PL \/ EN<\/button>\n      <button class=\"fb-lang-btn\" data-lang=\"EN_FR\">EN \/ FR<\/button>\n      <button class=\"fb-lang-btn\" data-lang=\"EN_DE\">EN \/ DE<\/button>\n    <\/div>\n\n    <!-- 2. Nawigacja + Zoom + Pe\u0142ny ekran + Pobieranie -->\n    <div class=\"fb-controls-group is-disabled\" id=\"fb-controls\">\n      <!-- Przewracanie stron -->\n      <div class=\"fb-pill\">\n        <button class=\"fb-btn\" id=\"fb-prev\" title=\"Poprzednia strona\">\u2b05 <span class=\"hide-mobile-text\">POPRZEDNIA<\/span><\/button>\n        <span class=\"fb-counter\" id=\"fb-counter\">Strona 1<\/span>\n        <button class=\"fb-btn\" id=\"fb-next\" title=\"Nast\u0119pna strona\"><span class=\"hide-mobile-text\">NAST\u0118PNA<\/span> \u27a1<\/button>\n      <\/div>\n\n      <!-- Zoom In \/ Zoom Out -->\n      <div class=\"fb-pill\">\n        <button class=\"fb-btn fb-btn-secondary fb-btn-icon\" id=\"fb-zoom-out\" title=\"Oddal (Zoom Out)\">\ud83d\udd0d\u2212<\/button>\n        <span class=\"fb-zoom-label\" id=\"fb-zoom-label\" title=\"Kliknij, aby zresetowa\u0107 powi\u0119kszenie\">100%<\/span>\n        <button class=\"fb-btn fb-btn-secondary fb-btn-icon\" id=\"fb-zoom-in\" title=\"Przybli\u017c (Zoom In)\">\ud83d\udd0d+<\/button>\n      <\/div>\n\n      <!-- Akcje (Pobierz PDF + Pe\u0142ny ekran) -->\n      <div class=\"fb-pill\">\n        <a class=\"fb-btn fb-btn-secondary\" id=\"fb-download\" href=\"https:\/\/viallidesign.com\/katalogi\/Vialli_Design2026.pdf\" download=\"Vialli_Design2026.pdf\" target=\"_blank\" title=\"Pobierz aktualn\u0105 wersj\u0119 PDF\">\n          \u2b07 <span class=\"hide-mobile-text\">Pobierz<\/span> PDF\n        <\/a>\n        <button class=\"fb-btn\" id=\"fb-fullscreen\" title=\"Prze\u0142\u0105cz pe\u0142ny ekran\">\u26f6 <span class=\"hide-mobile-text\">Pe\u0142ny ekran<\/span><\/button>\n      <\/div>\n    <\/div>\n  <\/div>\n\n  <!-- SCENA KATALOGU PONI\u017bEJ PASKA -->\n  <div class=\"fb-stage\" id=\"fb-stage\">\n    <!-- Pasek \u0142adowania w tle -->\n    <div class=\"fb-loader\" id=\"fb-loader\">\n      <div class=\"fb-loader-text\" id=\"fb-loader-text\">Pobieranie katalogu&#8230;<\/div>\n      <div class=\"fb-progress-track\">\n        <div class=\"fb-progress-bar\" id=\"fb-progress-bar\"><\/div>\n      <\/div>\n    <\/div>\n\n    <!-- Warstwa Zoom & Pan -->\n    <div class=\"fb-zoom-layer\" id=\"fb-zoom-layer\">\n      <div class=\"fb-viewport\" id=\"fb-viewport\"><\/div>\n    <\/div>\n  <\/div>\n\n  <!-- Biblioteki zewn\u0119trzne PDF.js oraz StPageFlip -->\n  <script src=\"https:\/\/cdnjs.cloudflare.com\/ajax\/libs\/pdf.js\/2.16.105\/pdf.min.js\"><\/script>\n  <script src=\"https:\/\/cdn.jsdelivr.net\/npm\/page-flip@2.0.7\/dist\/js\/page-flip.browser.js\"><\/script>\n\n  <script>\n    (function() {\n      \/\/ =================================================================\n      \/\/ LINKI DO 3 WERSJI J\u0118ZYKOWYCH KATALOGU VIALLI DESIGN 2026:\n      const catalogs = {\n        'PL_EN': 'https:\/\/viallidesign.com\/katalogi\/Vialli_Design2026.pdf',\n        'EN_FR': 'https:\/\/viallidesign.com\/katalogi\/Vialli_Design2026_EN_FR.pdf',\n        'EN_DE': 'https:\/\/viallidesign.com\/katalogi\/Vialli_Design2026_EN_DE.pdf'\n      };\n      \/\/ =================================================================\n\n      \/\/ Zwi\u0119kszona ostro\u015b\u0107 renderowania (2.2), aby tekst przy Zoomie by\u0142 \u017cyleta\n      const renderScale = 2.2;\n      pdfjsLib.GlobalWorkerOptions.workerSrc = 'https:\/\/cdnjs.cloudflare.com\/ajax\/libs\/pdf.js\/2.16.105\/pdf.worker.min.js';\n\n      const widget = document.getElementById('moj-flipbook-widget');\n      const stageEl = document.getElementById('fb-stage');\n      const zoomLayer = document.getElementById('fb-zoom-layer');\n      const viewportEl = document.getElementById('fb-viewport');\n      const loader = document.getElementById('fb-loader');\n      const loaderText = document.getElementById('fb-loader-text');\n      const progressBar = document.getElementById('fb-progress-bar');\n      const controls = document.getElementById('fb-controls');\n      const pageCounter = document.getElementById('fb-counter');\n      const zoomLabel = document.getElementById('fb-zoom-label');\n      const downloadBtn = document.getElementById('fb-download');\n      const fullscreenBtn = document.getElementById('fb-fullscreen');\n      const langButtons = widget.querySelectorAll('.fb-lang-btn');\n\n      let pageFlip = null;\n      let isRendering = false;\n      let currentLang = 'PL_EN';\n\n      \/\/ Bufor wyrenderowanych stron (umo\u017cliwia natychmiastowe powi\u0119kszenie na Fullscreenie bez ponownego pobierania PDF)\n      let cachedCanvases = [];\n      let pageAspectRatio = 0.707;\n      let totalPagesCount = 0;\n      let savedPageIndex = 0;\n\n      \/\/ Zmienne stanu dla funkcji Zoom & Pan (przesuwanie przybli\u017conego katalogu)\n      let zoomLevel = 1;\n      const minZoom = 1;\n      const maxZoom = 2.5;\n      const zoomStep = 0.25;\n      let panX = 0;\n      let panY = 0;\n      let isDragging = false;\n      let dragStartX = 0;\n      let dragStartY = 0;\n\n      function updateDownloadLink(langKey) {\n        const url = catalogs[langKey];\n        const fileName = url.split('\/').pop();\n        downloadBtn.href = url;\n        downloadBtn.setAttribute('download', fileName);\n      }\n\n      \/\/ --- OBS\u0141UGA ZOOM IN \/ ZOOM OUT ORAZ PRZESUWANIA ---\n      function applyZoomTransform() {\n        if (zoomLevel <= 1) {\n          zoomLevel = 1;\n          panX = 0;\n          panY = 0;\n          zoomLayer.classList.remove('is-zoomed');\n        } else {\n          zoomLayer.classList.add('is-zoomed');\n        }\n        zoomLayer.style.transform = `translate(${panX}px, ${panY}px) scale(${zoomLevel})`;\n        zoomLabel.innerText = `${Math.round(zoomLevel * 100)}%`;\n      }\n\n      function changeZoom(delta) {\n        zoomLevel = Math.min(maxZoom, Math.max(minZoom, +(zoomLevel + delta).toFixed(2)));\n        applyZoomTransform();\n      }\n\n      function resetZoom() {\n        zoomLevel = 1;\n        panX = 0;\n        panY = 0;\n        applyZoomTransform();\n      }\n\n      \/\/ Przesuwanie myszk\u0105 po przybli\u017ceniu\n      stageEl.addEventListener('mousedown', (e) => {\n        if (zoomLevel <= 1) return;\n        isDragging = true;\n        zoomLayer.classList.add('is-dragging');\n        dragStartX = e.clientX - panX;\n        dragStartY = e.clientY - panY;\n        e.preventDefault();\n      });\n\n      window.addEventListener('mousemove', (e) => {\n        if (!isDragging) return;\n        panX = e.clientX - dragStartX;\n        panY = e.clientY - dragStartY;\n        zoomLayer.style.transform = `translate(${panX}px, ${panY}px) scale(${zoomLevel})`;\n      });\n\n      window.addEventListener('mouseup', () => {\n        if (isDragging) {\n          isDragging = false;\n          zoomLayer.classList.remove('is-dragging');\n        }\n      });\n\n      \/\/ Przesuwanie palcem na telefonie po przybli\u017ceniu\n      stageEl.addEventListener('touchstart', (e) => {\n        if (zoomLevel <= 1 || e.touches.length !== 1) return;\n        isDragging = true;\n        zoomLayer.classList.add('is-dragging');\n        dragStartX = e.touches[0].clientX - panX;\n        dragStartY = e.touches[0].clientY - panY;\n      }, { passive: true });\n\n      stageEl.addEventListener('touchmove', (e) => {\n        if (!isDragging || zoomLevel <= 1 || e.touches.length !== 1) return;\n        panX = e.touches[0].clientX - dragStartX;\n        panY = e.touches[0].clientY - dragStartY;\n        zoomLayer.style.transform = `translate(${panX}px, ${panY}px) scale(${zoomLevel})`;\n        e.preventDefault();\n      }, { passive: false });\n\n      stageEl.addEventListener('touchend', () => {\n        isDragging = false;\n        zoomLayer.classList.remove('is-dragging');\n      });\n\n      \/\/ Obs\u0142uga Ctrl + K\u00f3\u0142ko myszy do przybli\u017cania\n      stageEl.addEventListener('wheel', (e) => {\n        if (e.ctrlKey || zoomLevel > 1) {\n          e.preventDefault();\n          const delta = e.deltaY < 0 ? zoomStep : -zoomStep;\n          changeZoom(delta);\n        }\n      }, { passive: false });\n\n      \/\/ --- FUNKCJA BUDUJ\u0104CA KSI\u0104\u017bK\u0118 DO AKTUALNEGO ROZMIARU EKRANU (PC \/ FULLSCREEN \/ TELEFON) ---\n      function buildBookLayout(startPageIndex = 0) {\n        if (!cachedCanvases.length) return;\n\n        if (pageFlip) {\n          try {\n            startPageIndex = pageFlip.getCurrentPageIndex();\n          } catch (e) {}\n          pageFlip.destroy();\n          pageFlip = null;\n        }\n\n        viewportEl.innerHTML = '<div id=\"fb-book\"><\/div>';\n        const flipbookEl = document.getElementById('fb-book');\n        const fragment = document.createDocumentFragment();\n\n        cachedCanvases.forEach((canvas, idx) => {\n          const pageNum = idx + 1;\n          const pageDiv = document.createElement('div');\n          pageDiv.className = 'fb-page';\n          if (pageNum === 1 || pageNum === totalPagesCount) {\n            pageDiv.setAttribute('data-density', 'hard');\n          }\n          pageDiv.appendChild(canvas);\n          fragment.appendChild(pageDiv);\n        });\n\n        flipbookEl.appendChild(fragment);\n\n        \/\/ Pobranie dok\u0142adnych wymiar\u00f3w sceny (na pe\u0142nym ekranie s\u0105 znacznie wi\u0119ksze)\n        const availW = viewportEl.clientWidth;\n        const availH = viewportEl.clientHeight;\n        \/\/ Na telefonie (lub w\u0105skim oknie) wy\u015bwietlamy 1 du\u017c\u0105 stron\u0119 zamiast 2 ma\u0142ych\n        const isMobilePortrait = availW < 768 || (availH > availW * 1.15);\n\n        let pageH = availH * 0.98;\n        let pageW = pageH * pageAspectRatio;\n\n        if (isMobilePortrait) {\n          \/\/ Tryb 1 strony (wype\u0142nia szeroko\u015b\u0107 telefonu)\n          if (pageW > availW * 0.98) {\n            pageW = availW * 0.98;\n            pageH = pageW \/ pageAspectRatio;\n          }\n        } else {\n          \/\/ Tryb 2 stron obok siebie (rozk\u0142ad\u00f3wka na PC \/ Fullscreen)\n          if (pageW * 2 > availW * 0.98) {\n            pageW = (availW * 0.98) \/ 2;\n            pageH = pageW \/ pageAspectRatio;\n          }\n        }\n\n        pageFlip = new St.PageFlip(flipbookEl, {\n          width: Math.floor(pageW),\n          height: Math.floor(pageH),\n          size: 'fixed',\n          maxShadowOpacity: 0.35,\n          showCover: true,\n          usePortrait: isMobilePortrait,\n          startPage: startPageIndex,\n          mobileScrollSupport: false\n        });\n\n        pageFlip.loadFromHTML(flipbookEl.querySelectorAll('.fb-page'));\n\n        pageFlip.on('flip', (e) => {\n          savedPageIndex = e.data;\n          pageCounter.innerText = `Strona ${savedPageIndex + 1} z ${totalPagesCount}`;\n        });\n\n        savedPageIndex = startPageIndex;\n        pageCounter.innerText = `Strona ${savedPageIndex + 1} z ${totalPagesCount}`;\n      }\n\n      \/\/ --- POBIERANIE I RENDEROWANIE PLIKU PDF ---\n      async function loadCatalog(langKey) {\n        if (isRendering) return;\n        isRendering = true;\n\n        resetZoom();\n        const pdfUrl = catalogs[langKey];\n        updateDownloadLink(langKey);\n\n        viewportEl.classList.remove('is-ready');\n        controls.classList.add('is-disabled');\n        loader.style.display = 'block';\n        progressBar.style.width = '0%';\n        loaderText.innerText = `\u0141\u0105czenie z serwerem (${langKey.replace('_', ' \/ ')})...`;\n\n        if (pageFlip) {\n          pageFlip.destroy();\n          pageFlip = null;\n        }\n        cachedCanvases = [];\n        savedPageIndex = 0;\n\n        try {\n          const pdf = await pdfjsLib.getDocument(pdfUrl).promise;\n          totalPagesCount = pdf.numPages;\n\n          const firstPage = await pdf.getPage(1);\n          const initialViewport = firstPage.getViewport({ scale: 1 });\n          pageAspectRatio = initialViewport.width \/ initialViewport.height;\n\n          for (let pageNum = 1; pageNum <= totalPagesCount; pageNum++) {\n            const percent = Math.round((pageNum \/ totalPagesCount) * 100);\n            loaderText.innerText = `Wczytywanie stron: ${pageNum} z ${totalPagesCount} (${percent}%)`;\n            progressBar.style.width = `${percent}%`;\n            \n            const page = await pdf.getPage(pageNum);\n            const viewport = page.getViewport({ scale: renderScale });\n\n            const canvas = document.createElement('canvas');\n            const context = canvas.getContext('2d');\n            canvas.width = viewport.width;\n            canvas.height = viewport.height;\n\n            await page.render({ canvasContext: context, viewport: viewport }).promise;\n            cachedCanvases.push(canvas);\n          }\n\n          \/\/ Z\u0142o\u017cenie katalogu w oparciu o aktualn\u0105 wielko\u015b\u0107 okna\n          buildBookLayout(0);\n\n          loader.style.display = 'none';\n          controls.classList.remove('is-disabled');\n          viewportEl.classList.add('is-ready');\n\n        } catch (error) {\n          console.error('B\u0142\u0105d \u0142adowania PDF:', error);\n          loaderText.innerText = `B\u0142\u0105d wczytywania pliku PDF (${langKey.replace('_', ' \/ ')}).`;\n          progressBar.style.background = '#ef4444';\n        } finally {\n          isRendering = false;\n        }\n      }\n\n      \/\/ --- PRZEBUDOWA WYMIAR\u00d3W PRZY WEJ\u015aCIU NA PE\u0141NY EKRAN LUB OBROCIE TELEFONU ---\n      let resizeTimer = null;\n      function handleResizeOrFullscreen() {\n        if (isRendering || !cachedCanvases.length) return;\n        clearTimeout(resizeTimer);\n        resizeTimer = setTimeout(() => {\n          resetZoom();\n          buildBookLayout(savedPageIndex);\n        }, 180);\n      }\n\n      window.addEventListener('resize', handleResizeOrFullscreen);\n      document.addEventListener('fullscreenchange', () => {\n        const isFs = !!document.fullscreenElement;\n        fullscreenBtn.innerHTML = isFs ? '\u2715 <span class=\"hide-mobile-text\">Zamknij<\/span>' : '\u26f6 <span class=\"hide-mobile-text\">Pe\u0142ny ekran<\/span>';\n        handleResizeOrFullscreen();\n      });\n\n      \/\/ Prze\u0142\u0105cznik j\u0119zyk\u00f3w\n      langButtons.forEach(btn => {\n        btn.addEventListener('click', () => {\n          const selectedLang = btn.getAttribute('data-lang');\n          if (selectedLang === currentLang || isRendering) return;\n\n          currentLang = selectedLang;\n          langButtons.forEach(b => b.classList.remove('active'));\n          btn.classList.add('active');\n\n          loadCatalog(selectedLang);\n        });\n      });\n\n      \/\/ Nawigacja prz\u00f3d \/ ty\u0142\n      document.getElementById('fb-prev').addEventListener('click', () => {\n        if (pageFlip) pageFlip.flipPrev();\n      });\n      document.getElementById('fb-next').addEventListener('click', () => {\n        if (pageFlip) pageFlip.flipNext();\n      });\n\n      \/\/ Przyciski Zoom In \/ Zoom Out \/ Reset\n      document.getElementById('fb-zoom-in').addEventListener('click', () => changeZoom(zoomStep));\n      document.getElementById('fb-zoom-out').addEventListener('click', () => changeZoom(-zoomStep));\n      zoomLabel.addEventListener('click', resetZoom);\n\n      \/\/ Przycisk Pe\u0142nego ekranu (z fallbackiem dla iPhone\/iOS Safari, kt\u00f3re nie wspiera natywnego API Fullscreen dla div\u00f3w)\n      fullscreenBtn.addEventListener('click', () => {\n        if (widget.requestFullscreen) {\n          if (!document.fullscreenElement) {\n            widget.requestFullscreen().catch(err => console.warn(err));\n          } else {\n            document.exitFullscreen();\n          }\n        } else if (widget.webkitRequestFullscreen) {\n          widget.webkitRequestFullscreen();\n        }\n      });\n\n      \/\/ Start domy\u015blnej wersji\n      loadCatalog(currentLang);\n    })();\n  <\/script>\n<\/div>\n<!-- === KONIEC WIDGETU KATALOGU VIALLI DESIGN 2026 === -->","protected":false},"excerpt":{"rendered":"<p>PL \/ EN EN \/ FR EN \/ DE \u2b05 POPRZEDNIA Strona 1 NAST\u0118PNA \u27a1 \ud83d\udd0d\u2212 100% \ud83d\udd0d+ \u2b07 Pobierz PDF \u26f6 Pe\u0142ny ekran Pobieranie katalogu&#8230;<\/p>","protected":false},"author":1,"featured_media":0,"parent":0,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"","meta":{"_uag_custom_page_level_css":"","site-sidebar-layout":"default","site-content-layout":"","ast-site-content-layout":"default","site-content-style":"default","site-sidebar-style":"default","ast-global-header-display":"","ast-banner-title-visibility":"","ast-main-header-display":"","ast-hfb-above-header-display":"","ast-hfb-below-header-display":"","ast-hfb-mobile-header-display":"","site-post-title":"","ast-breadcrumbs-content":"","ast-featured-img":"","footer-sml-layout":"","ast-disable-related-posts":"","theme-transparent-header-meta":"","adv-header-id-meta":"","stick-header-meta":"","header-above-stick-meta":"","header-main-stick-meta":"","header-below-stick-meta":"","astra-migrate-meta-layouts":"set","ast-page-background-enabled":"default","ast-page-background-meta":{"desktop":{"background-color":"","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"tablet":{"background-color":"","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"mobile":{"background-color":"","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""}},"ast-content-background-meta":{"desktop":{"background-color":"var(--ast-global-color-5)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"tablet":{"background-color":"var(--ast-global-color-5)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"mobile":{"background-color":"var(--ast-global-color-5)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""}},"footnotes":""},"class_list":["post-235945","page","type-page","status-publish","hentry"],"uagb_featured_image_src":{"full":false,"thumbnail":false,"medium":false,"medium_large":false,"large":false,"1536x1536":false,"2048x2048":false,"trp-custom-language-flag":false,"woocommerce_thumbnail":false,"woocommerce_single":false,"woocommerce_gallery_thumbnail":false,"dgwt-wcas-product-suggestion":false},"uagb_author_info":{"display_name":"viallidesign","author_link":"https:\/\/viallidesign.com\/en\/author\/viallidesign\/"},"uagb_comment_info":0,"uagb_excerpt":"PL \/ EN EN \/ FR EN \/ DE \u2b05 POPRZEDNIA Strona 1 NAST\u0118PNA \u27a1 \ud83d\udd0d\u2212 100% \ud83d\udd0d+ \u2b07 Pobierz PDF \u26f6 Pe\u0142ny ekran Pobieranie katalogu&#8230;","_links":{"self":[{"href":"https:\/\/viallidesign.com\/en\/wp-json\/wp\/v2\/pages\/235945","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/viallidesign.com\/en\/wp-json\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/viallidesign.com\/en\/wp-json\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/viallidesign.com\/en\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/viallidesign.com\/en\/wp-json\/wp\/v2\/comments?post=235945"}],"version-history":[{"count":4,"href":"https:\/\/viallidesign.com\/en\/wp-json\/wp\/v2\/pages\/235945\/revisions"}],"predecessor-version":[{"id":235954,"href":"https:\/\/viallidesign.com\/en\/wp-json\/wp\/v2\/pages\/235945\/revisions\/235954"}],"wp:attachment":[{"href":"https:\/\/viallidesign.com\/en\/wp-json\/wp\/v2\/media?parent=235945"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}