{"id":16,"date":"2026-01-02T14:49:01","date_gmt":"2026-01-02T13:49:01","guid":{"rendered":"https:\/\/prezentpaciora.szczepanskipawel.pl\/?page_id=16"},"modified":"2026-01-02T21:37:14","modified_gmt":"2026-01-02T20:37:14","slug":"elementor-16","status":"publish","type":"page","link":"https:\/\/prezentpaciora.szczepanskipawel.pl\/","title":{"rendered":"Elementor #16"},"content":{"rendered":"\t\t<div data-elementor-type=\"wp-post\" data-elementor-id=\"16\" class=\"elementor elementor-16\">\n\t\t\t\t<div class=\"elementor-element elementor-element-fd152da e-flex e-con-boxed e-con e-parent\" data-id=\"fd152da\" data-element_type=\"container\">\n\t\t\t\t\t<div class=\"e-con-inner\">\n\t\t\t\t<div class=\"elementor-element elementor-element-785dd2d elementor-widget elementor-widget-html\" data-id=\"785dd2d\" data-element_type=\"widget\" data-widget_type=\"html.default\">\n\t\t\t\t\t<!-- Fonts -->\n<link href=\"https:\/\/fonts.googleapis.com\/css2?family=Cinzel+Decorative:wght@400;700&family=Spectral:ital,wght@0,400;0,700;1,400&display=swap\" rel=\"stylesheet\">\n\n<!-- Tailwind -->\n<script src=\"https:\/\/cdn.tailwindcss.com\"><\/script>\n\n<style>\n  html, body { margin:0; padding:0; height:100%; background:#000; overflow:hidden; }\n\n  .elementor-section, .elementor-container, .elementor-column, .elementor-widget-wrap {\n    margin: 0 !important;\n    padding: 0 !important;\n  }\n\n  #magic-birthday-root, #magic-birthday-root * {\n    cursor: url('data:image\/svg+xml;utf8,<svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"48\" height=\"48\" viewBox=\"0 0 48 48\"><text y=\"35\" font-size=\"35\">\ud83e\uddf9<\/text><text x=\"10\" y=\"25\" font-size=\"20\">\u26a1<\/text><\/svg>'), auto !important;\n    box-sizing: border-box;\n  }\n\n  #magic-birthday-root {\n    display: block;\n    position: fixed !important;\n    inset: 0 !important;\n    width: 100vw !important;\n    height: 100vh !important;\n    overflow: hidden !important;\n    z-index: 9999999 !important;\n    background: #000;\n    font-family: 'Spectral', serif;\n    visibility: visible !important;\n    opacity: 1 !important;\n  }\n\n  :root {\n    --hogwarts-gold: #e2b13c;\n    --hogwarts-red: #740001;\n    --magic-glow: 0 0 25px rgba(226, 177, 60, 0.7);\n  }\n\n  .main-container {\n    position: absolute;\n    width: 100%;\n    height: 100%;\n    display: flex;\n    justify-content: center;\n    align-items: center;\n  }\n\n  \/* t\u0142o *\/\n  #hogwarts-bg {\n    position: absolute;\n    inset: 0;\n    background-image:\n      radial-gradient(circle at center, rgba(0,0,0,0.15), rgba(0,0,0,0.72)),\n      linear-gradient(to bottom, rgba(0,0,0,0.35), rgba(0,0,0,0.85)),\n      url('https:\/\/alfred.dailyweb.pl\/wp-content\/uploads\/2023\/02\/hogwart-legacy-1536x856.jpg');\n    background-size: cover;\n    background-position: center;\n    z-index: -2;\n    filter: saturate(0.95) contrast(1.08) brightness(0.55);\n    transform: scale(1.03);\n  }\n\n  #bg-vignette {\n    position: absolute;\n    inset: 0;\n    z-index: -1;\n    pointer-events: none;\n    background:\n      radial-gradient(circle at 20% 15%, rgba(226,177,60,0.08), rgba(0,0,0,0) 40%),\n      radial-gradient(circle at 80% 20%, rgba(255,255,255,0.05), rgba(0,0,0,0) 45%),\n      radial-gradient(circle at center, rgba(0,0,0,0), rgba(0,0,0,0.35) 70%, rgba(0,0,0,0.70));\n    mix-blend-mode: screen;\n  }\n\n  #stars-canvas {\n    position: absolute;\n    inset: 0;\n    z-index: 0;\n    pointer-events: none;\n    opacity: 0.95;\n  }\n\n  .wizard-font {\n    font-family: 'Cinzel Decorative', cursive;\n    color: var(--hogwarts-gold);\n    text-shadow: 0 0 15px rgba(226, 177, 60, 0.5);\n    display: block;\n  }\n\n  .header-wrapper {\n    position: absolute;\n    top: 10%;\n    width: 100%;\n    text-align: center;\n    z-index: 10;\n    padding: 0 20px;\n    pointer-events: none;\n    display: block;\n  }\n\n  \/* SNITCH *\/\n  #snitch {\n    position: absolute;\n    width: 78px;\n    height: 78px;\n    z-index: 110;\n    filter: drop-shadow(var(--magic-glow));\n    cursor: pointer;\n    user-select: none;\n    -webkit-tap-highlight-color: transparent;\n    pointer-events: auto;\n    touch-action: manipulation;\n  }\n\n  \/* du\u017cy hitbox zbieraj\u0105cy klik *\/\n  #snitch-hit {\n    position: absolute;\n    inset: -30px;\n    background: transparent;\n    pointer-events: auto;\n  }\n\n  \/* SVG NIE \u0142apie klik\u00f3w *\/\n  #snitch svg { pointer-events: none; }\n\n  @media (pointer: fine) and (min-width: 900px) {\n    #snitch { width: 92px; height: 92px; }\n    #snitch-hit { inset: -38px; }\n  }\n\n  .wing {\n    fill: #ffffff;\n    opacity: 0.9;\n    animation: flap 0.1s infinite alternate ease-in-out;\n    transform-box: fill-box;\n    transform-origin: 50% 50%;\n  }\n  @keyframes flap {\n    from { transform: rotate(40deg) scaleY(0.4); }\n    to   { transform: rotate(-60deg) scaleY(1.3); }\n  }\n\n  \/* HUD *\/\n  #hud {\n    position: fixed;\n    top: 16px;\n    left: 16px;\n    right: 86px;\n    z-index: 10000002;\n    display: flex;\n    align-items: center;\n    justify-content: space-between;\n    pointer-events: none;\n    gap: 12px;\n  }\n  .hud-chip {\n    pointer-events: none;\n    background: rgba(0,0,0,0.65);\n    border: 1px solid rgba(226,177,60,0.7);\n    color: #fff;\n    padding: 10px 12px;\n    border-radius: 999px;\n    box-shadow: 0 0 20px rgba(226,177,60,0.2);\n    backdrop-filter: blur(6px);\n    font-size: 14px;\n    display: inline-flex;\n    align-items: center;\n    gap: 10px;\n    white-space: nowrap;\n  }\n  #lives-hearts { display:inline-flex; gap:6px; align-items:center; font-size:18px; }\n  #timer { font-variant-numeric: tabular-nums; letter-spacing: 0.08em; }\n  #hits { font-family: 'Cinzel Decorative', cursive; color: var(--hogwarts-gold); letter-spacing: 0.08em; }\n\n  #start-tip {\n    position: fixed;\n    bottom: 28px;\n    left: 50%;\n    transform: translateX(-50%);\n    z-index: 10000002;\n    background: rgba(0,0,0,0.7);\n    border: 1px solid rgba(226,177,60,0.7);\n    color: #fff;\n    padding: 10px 14px;\n    border-radius: 999px;\n    box-shadow: 0 0 20px rgba(226,177,60,0.15);\n    backdrop-filter: blur(6px);\n    font-size: 14px;\n    pointer-events: none;\n    opacity: 1;\n    transition: opacity 0.3s ease;\n  }\n  #start-tip.hidden { opacity: 0; }\n\n  #music-control {\n    position: fixed;\n    top: 16px;\n    right: 16px;\n    z-index: 10000003;\n    background: rgba(0,0,0,0.8);\n    border: 2px solid var(--hogwarts-gold);\n    color: var(--hogwarts-gold);\n    width: 50px;\n    height: 50px;\n    border-radius: 50%;\n    display: flex;\n    justify-content: center;\n    align-items: center;\n    box-shadow: var(--magic-glow);\n    cursor: pointer;\n  }\n\n  #bludgers-layer { position:absolute; inset:0; z-index:70; pointer-events:auto; }\n  #bonus-layer    { position:absolute; inset:0; z-index:90; pointer-events:none; }\n  #particles      { position:absolute; inset:0; z-index:120; pointer-events:none; }\n\n  #toast {\n    position: fixed;\n    top: 72px;\n    left: 50%;\n    transform: translateX(-50%) translateY(-6px);\n    z-index: 10000004;\n    pointer-events: none;\n    opacity: 0;\n    transition: opacity 0.25s ease, transform 0.25s ease;\n    background: rgba(0,0,0,0.7);\n    border: 1px solid rgba(226,177,60,0.7);\n    color: #fff;\n    padding: 10px 14px;\n    border-radius: 999px;\n    backdrop-filter: blur(6px);\n    box-shadow: 0 0 25px rgba(226,177,60,0.12);\n    white-space: nowrap;\n  }\n  #toast.show { opacity: 1; transform: translateX(-50%) translateY(0); }\n\n  #overlay, #gameover {\n    display: none;\n    position: absolute;\n    inset: 0;\n    background: rgba(0, 0, 0, 0.95);\n    backdrop-filter: blur(10px);\n    z-index: 2000;\n    justify-content: center;\n    align-items: center;\n  }\n\n  .parchment {\n    background: #f4e4bc;\n    background-image: url('https:\/\/www.transparenttextures.com\/patterns\/paper.png');\n    color: #2c1e11;\n    padding: 2rem;\n    border-radius: 10px;\n    max-width: 560px;\n    width: 90%;\n    text-align: center;\n    box-shadow: 0 0 100px rgba(0,0,0,1);\n    border: 6px double #d4af37;\n    transform: rotate(-0.5deg);\n    display: block;\n    position: relative;\n  }\n\n  #letter-locked { display: block; }\n  #letter-open { display: none; }\n\n  .spell-area {\n    margin: 14px auto 0;\n    padding: 14px 14px;\n    border-radius: 10px;\n    border: 2px dashed rgba(44,30,17,0.35);\n    background: rgba(255,255,255,0.35);\n  }\n  .spell-btn {\n    background: #2c1e11;\n    color: #fff;\n    padding: 10px 18px;\n    border-radius: 999px;\n    border: 2px solid rgba(226,177,60,0.8);\n    font-family: 'Cinzel Decorative', cursive;\n    cursor: pointer;\n    display: inline-flex;\n    gap: 10px;\n    align-items: center;\n    justify-content: center;\n  }\n  .wand {\n    display: inline-block;\n    transform-origin: 20% 80%;\n  }\n  .cast .wand { animation: wandSwish 650ms ease; }\n  @keyframes wandSwish {\n    0% { transform: rotate(0deg) translateY(0); }\n    35% { transform: rotate(-20deg) translateY(-2px); }\n    70% { transform: rotate(24deg) translateY(1px); }\n    100% { transform: rotate(0deg) translateY(0); }\n  }\n\n  .magic-burst {\n    position: absolute;\n    inset: -40px;\n    pointer-events: none;\n    opacity: 0;\n    background: radial-gradient(circle at center,\n      rgba(226,177,60,0.35),\n      rgba(226,177,60,0.12),\n      rgba(0,0,0,0));\n    filter: blur(2px);\n  }\n  .cast .magic-burst { animation: burst 650ms ease; }\n  @keyframes burst {\n    0% { opacity: 0; transform: scale(0.94); }\n    40% { opacity: 1; transform: scale(1.0); }\n    100% { opacity: 0; transform: scale(1.08); }\n  }\n\n  .reveal { animation: reveal 420ms ease; }\n  @keyframes reveal {\n    from { opacity: 0; transform: translateY(10px) scale(0.98); }\n    to   { opacity: 1; transform: translateY(0) scale(1); }\n  }\n\n  #qrcode {\n    background: #fff;\n    padding: 8px;\n    border: 3px solid var(--hogwarts-gold);\n    margin: 15px auto;\n    display: inline-block;\n  }\n  #qrcode img {\n    display: block;\n    width: 180px;\n    height: 180px;\n    object-fit: contain;\n  }\n\n  .btn-magic, .btn-ghost {\n    padding: 10px 25px;\n    border-radius: 6px;\n    font-family: 'Cinzel Decorative', cursive;\n    margin-top: 10px;\n    display: inline-block;\n    cursor: pointer;\n  }\n  .btn-magic { background: var(--hogwarts-red); color: white; border: 1px solid var(--hogwarts-gold); }\n  .btn-ghost { background: rgba(0,0,0,0.75); color: #fff; border: 1px solid rgba(226,177,60,0.8); }\n\n  .bludger {\n    position: absolute;\n    width: 56px;\n    height: 56px;\n    border-radius: 50%;\n    background: radial-gradient(circle at 30% 30%, #666, #0b0b0b);\n    box-shadow: inset -7px -7px 14px rgba(0,0,0,0.85),\n                0 0 30px rgba(0,0,0,0.9);\n    pointer-events: auto;\n    user-select: none;\n  }\n  .bludger::after {\n    content: \"\";\n    position: absolute;\n    inset: 8px;\n    border-radius: 50%;\n    background: radial-gradient(circle at 30% 30%, #888, #1a1a1a);\n    box-shadow: inset 0 0 10px rgba(0,0,0,0.6);\n  }\n\n  .flash-hit {\n    position: fixed;\n    inset: 0;\n    z-index: 10000001;\n    pointer-events: none;\n    background: radial-gradient(circle at center, rgba(255,70,70,0.12), rgba(0,0,0,0));\n    opacity: 0;\n    transition: opacity 0.12s ease;\n  }\n  .flash-hit.on { opacity: 1; }\n\n  .snitch-pulse { animation: snitchPulse 0.22s ease; }\n  @keyframes snitchPulse { 0%{transform:scale(1)} 60%{transform:scale(1.12)} 100%{transform:scale(1)} }\n\n  .spark {\n    position: absolute;\n    width: 6px;\n    height: 6px;\n    border-radius: 50%;\n    background: rgba(226,177,60,0.9);\n    box-shadow: 0 0 18px rgba(226,177,60,0.55);\n    transform: translate(-50%,-50%);\n    animation: spark 700ms ease-out forwards;\n  }\n  @keyframes spark {\n    0% { opacity: 1; transform: translate(-50%,-50%) scale(1); }\n    100% { opacity: 0; transform: translate(calc(-50% + var(--dx)), calc(-50% + var(--dy))) scale(0.2); }\n  }\n<\/style>\n\n<div id=\"magic-birthday-root\">\n  <div class=\"main-container\">\n    <div id=\"hogwarts-bg\"><\/div>\n    <div id=\"bg-vignette\"><\/div>\n    <canvas id=\"stars-canvas\"><\/canvas>\n\n    <div class=\"header-wrapper\">\n      <h1 class=\"wizard-font text-2xl md:text-5xl mb-4\" style=\"font-size: clamp(1.5rem, 5vw, 3.5rem);\">\n        Paciora, Wszystkiego najlepszego z okazji 30 urodzin!\n      <\/h1>\n      <p class=\"text-lg md:text-2xl italic opacity-90 tracking-widest text-white\">\n        Le\u0107 na miotle i z\u0142ap Z\u0142oty Znicz!\n      <\/p>\n    <\/div>\n\n    <div id=\"bludgers-layer\"><\/div>\n    <div id=\"bonus-layer\"><\/div>\n    <div id=\"particles\"><\/div>\n\n    <div id=\"snitch\" title=\"Z\u0141AP MNIE!\">\n      <div id=\"snitch-hit\" aria-hidden=\"true\"><\/div>\n      <svg viewBox=\"0 0 100 100\" width=\"100%\" height=\"100%\">\n        <path class=\"wing\" d=\"M 50 45 C 10 -5 5 50 0 60\" stroke=\"white\" fill=\"none\" stroke-width=\"2.5\"\/>\n        <path class=\"wing\" d=\"M 50 45 C 90 -5 95 50 100 60\" stroke=\"white\" fill=\"none\" stroke-width=\"2.5\"\/>\n        <circle cx=\"50\" cy=\"50\" r=\"16\" fill=\"url(#goldGrad)\" stroke=\"#8e6b1d\" stroke-width=\"1.5\"\/>\n        <defs>\n          <linearGradient id=\"goldGrad\" x1=\"0%\" y1=\"0%\" x2=\"100%\" y2=\"100%\">\n            <stop offset=\"0%\" style=\"stop-color:#fff2ac\"\/>\n            <stop offset=\"50%\" style=\"stop-color:#e2b13c\"\/>\n            <stop offset=\"100%\" style=\"stop-color:#8e6b1d\"\/>\n          <\/linearGradient>\n        <\/defs>\n      <\/svg>\n    <\/div>\n  <\/div>\n\n  <div id=\"toast\"><\/div>\n\n  <div id=\"hud\">\n    <div class=\"hud-chip\">\n      <span>\u017bycia:<\/span>\n      <span id=\"lives-hearts\"><\/span>\n      <span style=\"opacity:.8\">\u2022<\/span>\n      <span id=\"hits\">Znicz: 0\/3<\/span>\n    <\/div>\n    <div class=\"hud-chip\">\n      <span style=\"opacity:.85\">Czas:<\/span>\n      <span id=\"timer\">01:00<\/span>\n    <\/div>\n  <\/div>\n\n  <div id=\"start-tip\">Kliknij ekran, \u017ceby rozpocz\u0105\u0107 (i uruchomi\u0107 muzyk\u0119)<\/div>\n  <div class=\"flash-hit\" id=\"flash\"><\/div>\n\n  <button id=\"music-control\" type=\"button\" aria-label=\"Muzyka\">\n    <span id=\"music-icon\" style=\"font-size: 24px;\">\ud83d\udd07<\/span>\n  <\/button>\n\n  <audio id=\"hedwig-audio\" loop preload=\"auto\" playsinline>\n    <source src=\"https:\/\/prezentpaciora.szczepanskipawel.pl\/wp-content\/uploads\/2026\/01\/John_Williams_-_Hedwigs_Theme_OST_Harry_Potter_mp3.pm_.mp3\" type=\"audio\/mpeg\">\n  <\/audio>\n\n  <div id=\"overlay\">\n    <div class=\"parchment\" id=\"letter\">\n      <div class=\"magic-burst\"><\/div>\n\n      <h2 class=\"wizard-font text-2xl mb-2\" style=\"color: #2c1e11;\">Magiczny List<\/h2>\n      <div class=\"w-24 h-0.5 bg-black opacity-10 mx-auto mb-4\"><\/div>\n\n      <div id=\"letter-locked\">\n        <p class=\"text-base italic mb-3\">\n          List jest <b>zapiecz\u0119towany magi\u0105<\/b>.<br>\n          U\u017cyj r\u00f3\u017cd\u017cki i rzu\u0107 zakl\u0119cie, aby go otworzy\u0107.\n        <\/p>\n\n        <div class=\"spell-area\">\n          <button class=\"spell-btn\" id=\"cast-spell\" type=\"button\">\n            <span class=\"wand\">\ud83e\ude84<\/span>\n            <span>Rzu\u0107 zakl\u0119cie: <b>Revelio<\/b><\/span>\n          <\/button>\n          <div class=\"text-[11px] mt-2 uppercase tracking-widest font-bold opacity-70\">\n            Kliknij przycisk, aby ods\u0142oni\u0107 kod\n          <\/div>\n        <\/div>\n\n        <button class=\"btn-ghost\" id=\"close-btn-locked\" type=\"button\">Zamknij<\/button>\n      <\/div>\n\n      <div id=\"letter-open\" class=\"reveal\">\n        <p class=\"text-base italic mb-4\">\n          \"Uroczy\u015bcie przysi\u0119gam, \u017ce knuj\u0119 co\u015b niedobrego...\"<br><br>\n          <b>Paciora!<\/b> Z okazji Twoich <b>30 urodzin<\/b>,<br>\n          Ministerstwo Magii przesy\u0142a ten bilet do przygody.\n        <\/p>\n\n        <div id=\"qrcode\">\n          <img\n            src=\"https:\/\/prezentpaciora.szczepanskipawel.pl\/wp-content\/uploads\/2026\/01\/Zrzut-ekranu-2026-01-2-o-20.37.16.png?v=100\"\n            alt=\"Kod QR \u2013 prezent\"\n            loading=\"eager\"\n            decoding=\"async\"\n          >\n        <\/div>\n\n        <p class=\"text-[10px] uppercase tracking-widest font-bold\">Zeskanuj kod zakl\u0119ciem 'Revelio'<\/p>\n        <button class=\"btn-magic\" id=\"close-btn\" type=\"button\">Zamknij list<\/button>\n      <\/div>\n    <\/div>\n  <\/div>\n\n  <div id=\"gameover\">\n    <div class=\"parchment\" id=\"gameover-card\">\n      <h2 class=\"wizard-font text-2xl mb-2\" style=\"color: #2c1e11;\">Koniec gry!<\/h2>\n      <div class=\"w-24 h-0.5 bg-black opacity-10 mx-auto mb-4\"><\/div>\n      <p class=\"text-base italic mb-2\" id=\"gameover-reason\">Spr\u00f3buj jeszcze raz!<\/p>\n      <button class=\"btn-magic\" id=\"restart-btn\" type=\"button\">Zagraj od nowa<\/button>\n      <button class=\"btn-ghost\" id=\"close-gameover-btn\" type=\"button\">Zamknij<\/button>\n    <\/div>\n  <\/div>\n<\/div>\n\n<script>\n(function(){\n  const isDesktop = matchMedia('(pointer: fine)').matches && innerWidth >= 900;\n\n  const CFG = {\n    timeLimitSec: 60,\n    lives: 3,\n\n    \/* \u2705 +10% pr\u0119dko\u015bci znicza (baza i narastanie) *\/\n    snitchSpeedBase: 0.0352,        \/* by\u0142o 0.032 *\/\n    snitchSpeedRampPerSec: 0.000418,\/* by\u0142o 0.00038 *\/\n    desktopSpeedMultiplier: isDesktop ? 0.86 : 1.0,\n\n    snitchFreezeAfterHitMs: 150,\n    snitchHitsToWin: 3,\n    snitchHitCooldownMs: 210,\n\n    bludgerCount: 6,\n    bludgerBaseSpeed: 3.1,\n    bludgerSpeedRampPerSec: 0.05,\n\n    hitCooldownMs: 650,\n    cursorHitRadius: 34,\n    pointerFreshMs: 700,\n\n    pickupEveryMs: 9000,\n    pickupLifeMs: 7000\n  };\n\n  const $ = (id) => document.getElementById(id);\n\n  const root = $('magic-birthday-root');\n  const audio = $('hedwig-audio');\n  const musicIcon = $('music-icon');\n  const musicBtn = $('music-control');\n\n  const overlay = $('overlay');\n  const letter = $('letter');\n  const closeBtn = $('close-btn');\n  const closeBtnLocked = $('close-btn-locked');\n  const castSpellBtn = $('cast-spell');\n\n  const gameover = $('gameover');\n  const gameoverCard = $('gameover-card');\n  const gameoverReasonEl = $('gameover-reason');\n  const restartBtn = $('restart-btn');\n  const closeGameoverBtn = $('close-gameover-btn');\n\n  const startTip = $('start-tip');\n  const livesHearts = $('lives-hearts');\n  const timerEl = $('timer');\n  const flash = $('flash');\n  const toast = $('toast');\n  const hitsEl = $('hits');\n\n  const snitch = $('snitch');\n  const bludgersLayer = $('bludgers-layer');\n  const bonusLayer = $('bonus-layer');\n  const particlesLayer = $('particles');\n\n  audio.muted = false;\n  audio.volume = 1.0;\n\n  let playing = false;\n  let hasInteracted = false;\n\n  let started = false;\n  let ended = false;\n\n  let lives = CFG.lives;\n  let timeLeft = CFG.timeLimitSec;\n  let timerInterval = null;\n\n  let snitchHits = 0;\n  let lastSnitchHitAt = 0;\n\n  const pointer = { x: innerWidth\/2, y: innerHeight\/2, active: false };\n  let lastPointerMoveAt = 0;\n\n  addEventListener('mousemove', (e) => {\n    pointer.x = e.clientX; pointer.y = e.clientY;\n    pointer.active = true;\n    lastPointerMoveAt = Date.now();\n  }, { passive:true });\n\n  addEventListener('touchmove', (e) => {\n    if (e.touches && e.touches[0]) {\n      pointer.x = e.touches[0].clientX; pointer.y = e.touches[0].clientY;\n      pointer.active = true;\n      lastPointerMoveAt = Date.now();\n    }\n  }, { passive:true });\n\n  function showToast(text){\n    toast.textContent = text;\n    toast.classList.add('show');\n    clearTimeout(showToast._t);\n    showToast._t = setTimeout(() => toast.classList.remove('show'), 1600);\n  }\n\n  function startAudio(){\n    audio.play().then(() => {\n      musicIcon.textContent = '\ud83c\udfb5';\n      playing = true;\n    }).catch((e) => console.log(\"Audio b\u0142\u0105d:\", e));\n  }\n\n  function toggleMusic(e){\n    e.stopPropagation();\n    if (!playing) startAudio();\n    else {\n      audio.pause();\n      musicIcon.textContent = '\ud83d\udd07';\n      playing = false;\n    }\n  }\n\n  function renderLives(){\n    livesHearts.textContent = '';\n    for (let i=0;i<lives;i++) livesHearts.append(Object.assign(document.createElement('span'), {textContent:'\u2764\ufe0f'}));\n    if (lives === 0) livesHearts.append(Object.assign(document.createElement('span'), {textContent:'\ud83d\udc80'}));\n  }\n\n  function renderHits(){\n    hitsEl.textContent = `Znicz: ${snitchHits}\/${CFG.snitchHitsToWin}`;\n  }\n\n  function fmtTime(sec){\n    const s = Math.max(0, sec);\n    const mm = String(Math.floor(s\/60)).padStart(2,'0');\n    const ss = String(s%60).padStart(2,'0');\n    return `${mm}:${ss}`;\n  }\n\n  let pickupTimer = null;\n\n  function stopRunningTimers(){\n    if (timerInterval) clearInterval(timerInterval);\n    timerInterval = null;\n    clearTimeout(pickupTimer);\n    pickupTimer = null;\n  }\n\n  function startGame(){\n    if (started) return;\n    started = true;\n    ended = false;\n\n    startTip.classList.add('hidden');\n    timerEl.textContent = fmtTime(timeLeft);\n\n    timerInterval = setInterval(() => {\n      if (ended) return;\n      timeLeft -= 1;\n      timerEl.textContent = fmtTime(timeLeft);\n      if (timeLeft <= 0) triggerGameOver(\"Czas min\u0105\u0142!\");\n    }, 1000);\n\n    scheduleNextPickup();\n  }\n\n  function resetStateForNewGame(){\n    stopRunningTimers();\n\n    overlay.style.display = 'none';\n    gameover.style.display = 'none';\n\n    $('letter-locked').style.display = 'block';\n    $('letter-open').style.display = 'none';\n    letter.classList.remove('cast');\n\n    lives = CFG.lives;\n    timeLeft = CFG.timeLimitSec;\n    snitchHits = 0;\n    lastSnitchHitAt = 0;\n    lastHitAt = 0;\n    snitchFreezeUntil = 0;\n\n    started = false;\n    ended = false;\n\n    renderLives();\n    renderHits();\n    timerEl.textContent = fmtTime(timeLeft);\n\n    startTip.classList.remove('hidden');\n    startTip.textContent = \"Kliknij ekran, \u017ceby rozpocz\u0105\u0107 (i uruchomi\u0107 muzyk\u0119)\";\n\n    effects.bludgersSlowUntil = 0;\n    effects.accioUntil = 0;\n    effects.curseUntil = 0;\n\n    clearPickups();\n\n    bludgers.forEach(b => {\n      b.x = Math.random() * (innerWidth - b.size);\n      b.y = Math.random() * (innerHeight - b.size);\n      const dirx = Math.random() > 0.5 ? 1 : -1;\n      const diry = Math.random() > 0.5 ? 1 : -1;\n      b.vx = dirx * (CFG.bludgerBaseSpeed + Math.random()*2.2);\n      b.vy = diry * (CFG.bludgerBaseSpeed + Math.random()*2.2);\n    });\n\n    angle = 0;\n  }\n\n  function restartGame(e){\n    if (e) e.stopPropagation();\n    resetStateForNewGame();\n    startGame();\n  }\n\n  function handleRootClick(){\n    if (!hasInteracted) { startAudio(); hasInteracted = true; }\n\n    if (ended) {\n      restartGame();\n      return;\n    }\n\n    if (!started) startGame();\n  }\n\n  root.addEventListener('click', handleRootClick, { passive:true });\n  musicBtn.addEventListener('click', toggleMusic);\n\n  \/\/ Stars\n  const canvas = $('stars-canvas');\n  const ctx = canvas.getContext('2d');\n  let stars = [];\n\n  function initStars(){\n    canvas.width = innerWidth;\n    canvas.height = innerHeight;\n    stars = Array.from({length: 120}, () => ({\n      x: Math.random()*canvas.width,\n      y: Math.random()*canvas.height,\n      size: Math.random()*2 + 1,\n      speed: Math.random()*0.7 + 0.3,\n      opacity: Math.random()*0.45 + 0.25\n    }));\n  }\n  function drawStars(){\n    ctx.clearRect(0,0,canvas.width,canvas.height);\n    for (const p of stars) {\n      ctx.fillStyle = `rgba(255,255,255,${p.opacity})`;\n      ctx.beginPath();\n      ctx.arc(p.x,p.y,p.size,0,Math.PI*2);\n      ctx.fill();\n      p.y += p.speed;\n      if (p.y > canvas.height) p.y = -10;\n    }\n    requestAnimationFrame(drawStars);\n  }\n  addEventListener('resize', initStars);\n  document.addEventListener('visibilitychange', initStars);\n  initStars();\n  drawStars();\n\n  \/\/ Effects\n  const effects = { bludgersSlowUntil:0, accioUntil:0, curseUntil:0 };\n  const hasEffect = (t) => Date.now() < t;\n\n  \/\/ Snitch\n  let angle = 0;\n  let snitchFreezeUntil = 0;\n  let lastSnitchX = innerWidth\/2, lastSnitchY = innerHeight\/2;\n\n  function snitchSpeed(){\n    const elapsed = CFG.timeLimitSec - timeLeft;\n    let base = (CFG.snitchSpeedBase + elapsed*CFG.snitchSpeedRampPerSec) * CFG.desktopSpeedMultiplier;\n    if (hasEffect(effects.curseUntil)) base *= 1.18;\n    if (hasEffect(effects.accioUntil)) base *= 0.72;\n    return base;\n  }\n\n  function animateSnitch(){\n    if (!ended) {\n      const now = Date.now();\n      if (now < snitchFreezeUntil) {\n        snitch.style.left = lastSnitchX + 'px';\n        snitch.style.top = lastSnitchY + 'px';\n      } else {\n        angle += snitchSpeed();\n\n        const ampX = innerWidth  * (isDesktop ? 0.26 : 0.34);\n        const ampY = innerHeight * (isDesktop ? 0.18 : 0.26);\n\n        const half = (snitch.getBoundingClientRect().width \/ 2) || (isDesktop ? 46 : 39);\n\n        let x = (innerWidth\/2  - half) + Math.sin(angle*1.18) * ampX;\n        let y = (innerHeight\/2 - half) + Math.cos(angle*0.88) * ampY;\n\n        const size = half*2;\n        x = Math.max(0, Math.min(innerWidth  - size, x));\n        y = Math.max(0, Math.min(innerHeight - size, y));\n\n        lastSnitchX = x; lastSnitchY = y;\n        snitch.style.left = x + 'px';\n        snitch.style.top  = y + 'px';\n        snitch.style.transform = `rotate(${Math.sin(angle*2.0)*16}deg)`;\n      }\n    }\n    requestAnimationFrame(animateSnitch);\n  }\n  animateSnitch();\n\n  function spawnWinParticles(cx, cy){\n    for (let i=0;i<34;i++){\n      const p = document.createElement('div');\n      p.className = 'spark';\n      p.style.setProperty('--dx', (Math.random()*300 - 150).toFixed(0) + 'px');\n      p.style.setProperty('--dy', (Math.random()*300 - 150).toFixed(0) + 'px');\n      p.style.left = cx + 'px';\n      p.style.top = cy + 'px';\n      particlesLayer.appendChild(p);\n      setTimeout(() => p.remove(), 780);\n    }\n  }\n\n  function endGameShowTip(){\n    startTip.classList.remove('hidden');\n    startTip.textContent = \"Koniec! Kliknij ekran, \u017ceby zagra\u0107 ponownie.\";\n  }\n\n  function triggerWin(){\n    if (ended) return;\n    ended = true;\n    started = false;\n    stopRunningTimers();\n\n    const rect = snitch.getBoundingClientRect();\n    spawnWinParticles(rect.left + rect.width\/2, rect.top + rect.height\/2);\n\n    setTimeout(() => {\n      $('letter-locked').style.display = 'block';\n      $('letter-open').style.display = 'none';\n      letter.classList.remove('cast');\n      overlay.style.display = 'flex';\n      endGameShowTip();\n    }, 280);\n  }\n\n  function triggerGameOver(reason){\n    if (ended) return;\n    ended = true;\n    started = false;\n    stopRunningTimers();\n\n    gameoverReasonEl.textContent = reason || \"Koniec gry!\";\n    gameover.style.display = 'flex';\n    endGameShowTip();\n  }\n\n  snitch.addEventListener('click', (e) => {\n    e.stopPropagation();\n    if (ended) return;\n    if (!started) startGame();\n    if (!playing) startAudio();\n\n    const t = Date.now();\n    if (t - lastSnitchHitAt < CFG.snitchHitCooldownMs) return;\n    lastSnitchHitAt = t;\n\n    snitchHits += 1;\n    renderHits();\n\n    snitchFreezeUntil = Date.now() + CFG.snitchFreezeAfterHitMs;\n    snitch.classList.remove('snitch-pulse');\n    void snitch.offsetWidth;\n    snitch.classList.add('snitch-pulse');\n\n    if (snitchHits < CFG.snitchHitsToWin) showToast(`Trafienie! (${snitchHits}\/${CFG.snitchHitsToWin})`);\n    else { showToast('Z\u0142apany! \u2728'); triggerWin(); }\n  });\n\n  \/\/ Bludgers\n  const bludgers = [];\n  let lastHitAt = 0;\n\n  function dist(ax,ay,bx,by){\n    const dx=ax-bx, dy=ay-by;\n    return Math.sqrt(dx*dx+dy*dy);\n  }\n\n  function takeLife(){\n    const t = Date.now();\n    if (t - lastHitAt < CFG.hitCooldownMs) return;\n    lastHitAt = t;\n\n    lives = Math.max(0, lives - 1);\n    renderLives();\n    flash.classList.add('on');\n    setTimeout(() => flash.classList.remove('on'), 120);\n    showToast('T\u0142uczek! -1 \u2764\ufe0f');\n\n    if (lives <= 0) triggerGameOver(\"T\u0142uczki Ci\u0119 dopad\u0142y!\");\n  }\n\n  function bludgerSpeedMultiplier(){\n    const elapsed = CFG.timeLimitSec - timeLeft;\n    const ramp = 1 + elapsed*0.05;\n    const slow = hasEffect(effects.bludgersSlowUntil) ? 0.55 : 1;\n    return ramp * slow;\n  }\n\n  function createBludger(){\n    const el = document.createElement('div');\n    el.className = 'bludger';\n    bludgersLayer.appendChild(el);\n\n    const size = 56;\n    const base = 3.1;\n    const dirx = Math.random() > 0.5 ? 1 : -1;\n    const diry = Math.random() > 0.5 ? 1 : -1;\n\n    const b = {\n      el, size,\n      x: Math.random()*(innerWidth - size),\n      y: Math.random()*(innerHeight - size),\n      vx: dirx*(base + Math.random()*2.2),\n      vy: diry*(base + Math.random()*2.2)\n    };\n\n    el.addEventListener('click', (e) => {\n      e.stopPropagation();\n      if (ended) return;\n      if (!started) startGame();\n      b.vx *= -1.15;\n      b.vy *= -1.15;\n      showToast('Odbite! \ud83c\udfcf');\n    });\n\n    bludgers.push(b);\n  }\n\n  for (let i=0;i<6;i++) createBludger();\n\n  function animateBludgers(){\n    if (!ended) {\n      const mult = started ? bludgerSpeedMultiplier() : 1;\n      const pointerFresh = pointer.active && (Date.now() - lastPointerMoveAt < CFG.pointerFreshMs);\n\n      for (const b of bludgers) {\n        b.x += b.vx * mult;\n        b.y += b.vy * mult;\n\n        if (b.x < 0) { b.x = 0; b.vx *= -1; }\n        if (b.x > innerWidth - b.size) { b.x = innerWidth - b.size; b.vx *= -1; }\n        if (b.y < 0) { b.y = 0; b.vy *= -1; }\n        if (b.y > innerHeight - b.size) { b.y = innerHeight - b.size; b.vy *= -1; }\n\n        b.el.style.transform = `translate(${b.x}px, ${b.y}px)`;\n\n        if (started && pointerFresh) {\n          const bx = b.x + b.size\/2;\n          const by = b.y + b.size\/2;\n          if (dist(bx,by,pointer.x,pointer.y) < 34) takeLife();\n        }\n      }\n    }\n    requestAnimationFrame(animateBludgers);\n  }\n  animateBludgers();\n\n  \/\/ Pickups\n  let currentPickups = [];\n\n  function clearPickups(){\n    for (const p of currentPickups) p.el.remove();\n    currentPickups = [];\n  }\n\n  function scheduleNextPickup(){\n    if (ended) return;\n    pickupTimer = setTimeout(() => {\n      if (!ended && started) spawnPickup();\n      scheduleNextPickup();\n    }, 9000);\n  }\n\n  function rand(min,max){ return Math.random()*(max-min)+min; }\n\n  function spawnPickup(){\n    const isBonus = Math.random() < 0.60;\n    const type = isBonus ? (Math.random()<0.5?'felix':'accio') : (Math.random()<0.5?'curse':'time');\n    const icon = {felix:'\u2728', accio:'\ud83e\uddf2', curse:'\ud83d\udc80', time:'\u23f3'}[type];\n\n    const el = document.createElement('div');\n    el.className = 'pickup ' + (isBonus ? 'bonus' : 'trap');\n    el.textContent = icon;\n\n    el.style.left = rand(70, innerWidth-70) + 'px';\n    el.style.top  = rand(150, innerHeight-90) + 'px';\n\n    bonusLayer.appendChild(el);\n\n    const pickup = { el, type };\n    currentPickups.push(pickup);\n\n    el.addEventListener('click', (e) => {\n      e.stopPropagation();\n      if (ended) return;\n      if (!started) startGame();\n      applyPickup(type);\n      removePickup(pickup);\n    });\n\n    setTimeout(() => removePickup(pickup), 7000);\n  }\n\n  function removePickup(p){\n    if (!p || !p.el || !p.el.isConnected) return;\n    p.el.remove();\n    currentPickups = currentPickups.filter(x => x !== p);\n  }\n\n  function applyPickup(type){\n    const now = Date.now();\n    if (type === 'felix') { effects.bludgersSlowUntil = now + 6500; showToast('Felix Felicis! \u2728 T\u0142uczki wolniej'); }\n    if (type === 'accio') { effects.accioUntil = now + 6500; showToast('Accio! \ud83e\uddf2 Znicz przyci\u0105gany'); }\n    if (type === 'curse') { effects.curseUntil = now + 5200; showToast('Kl\u0105twa! \ud83d\udc80 Znicz szybszy'); }\n    if (type === 'time')  {\n      timeLeft = Math.max(0, timeLeft - 6);\n      timerEl.textContent = fmtTime(timeLeft);\n      showToast('Pu\u0142apka czasu! \u23f3 -6s');\n      if (timeLeft <= 0) triggerGameOver(\"Czas min\u0105\u0142!\");\n    }\n  }\n\n  \/\/ List\n  function closeOverlay(e){ e.stopPropagation(); overlay.style.display = 'none'; }\n  function revealQRCode(){\n    letter.classList.add('cast');\n    setTimeout(() => {\n      $('letter-locked').style.display = 'none';\n      const opened = $('letter-open');\n      opened.style.display = 'block';\n      opened.classList.remove('reveal');\n      void opened.offsetWidth;\n      opened.classList.add('reveal');\n    }, 520);\n  }\n\n  castSpellBtn.addEventListener('click', (e) => { e.stopPropagation(); revealQRCode(); });\n  closeBtnLocked.addEventListener('click', closeOverlay);\n  closeBtn.addEventListener('click', closeOverlay);\n  overlay.addEventListener('click', closeOverlay);\n  letter.addEventListener('click', (e)=>e.stopPropagation());\n\n  \/\/ Gameover UI\n  function closeGameOver(e){\n    e.stopPropagation();\n    gameover.style.display = 'none';\n  }\n\n  restartBtn.addEventListener('click', restartGame);\n  closeGameoverBtn.addEventListener('click', closeGameOver);\n  gameover.addEventListener('click', closeGameOver);\n  gameoverCard.addEventListener('click', (e)=>e.stopPropagation());\n\n  addEventListener('load', () => audio.load());\n\n  renderLives();\n  renderHits();\n  timerEl.textContent = fmtTime(timeLeft);\n})();\n<\/script>\t\t\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t","protected":false},"excerpt":{"rendered":"<p>Paciora, Wszystkiego najlepszego z okazji 30 urodzin! Le\u0107 na miotle i z\u0142ap Z\u0142oty Znicz! \u017bycia: \u2022 Znicz: 0\/3 Czas: 01:00 Kliknij ekran, \u017ceby rozpocz\u0105\u0107 (i uruchomi\u0107 muzyk\u0119) \ud83d\udd07 Magiczny List List jest zapiecz\u0119towany magi\u0105. U\u017cyj r\u00f3\u017cd\u017cki i rzu\u0107 zakl\u0119cie, aby go otworzy\u0107. \ud83e\ude84 Rzu\u0107 zakl\u0119cie: Revelio Kliknij przycisk, aby ods\u0142oni\u0107 kod Zamknij &#8220;Uroczy\u015bcie przysi\u0119gam, \u017ce [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"parent":0,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"elementor_canvas","meta":{"footnotes":""},"class_list":["post-16","page","type-page","status-publish","hentry"],"_links":{"self":[{"href":"https:\/\/prezentpaciora.szczepanskipawel.pl\/index.php?rest_route=\/wp\/v2\/pages\/16","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/prezentpaciora.szczepanskipawel.pl\/index.php?rest_route=\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/prezentpaciora.szczepanskipawel.pl\/index.php?rest_route=\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/prezentpaciora.szczepanskipawel.pl\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/prezentpaciora.szczepanskipawel.pl\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=16"}],"version-history":[{"count":61,"href":"https:\/\/prezentpaciora.szczepanskipawel.pl\/index.php?rest_route=\/wp\/v2\/pages\/16\/revisions"}],"predecessor-version":[{"id":83,"href":"https:\/\/prezentpaciora.szczepanskipawel.pl\/index.php?rest_route=\/wp\/v2\/pages\/16\/revisions\/83"}],"wp:attachment":[{"href":"https:\/\/prezentpaciora.szczepanskipawel.pl\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=16"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}