{"id":18,"date":"2025-10-31T12:05:32","date_gmt":"2025-10-31T12:05:32","guid":{"rendered":"https:\/\/525.cafe\/play-win\/"},"modified":"2025-12-29T10:39:56","modified_gmt":"2025-12-29T10:39:56","slug":"play-win","status":"publish","type":"page","link":"https:\/\/525.cafe\/ar\/play-win\/","title":{"rendered":"\u0627\u0644\u0639\u0628 \u0648\u0627\u0631\u0628\u062d"},"content":{"rendered":"<div data-elementor-type=\"wp-page\" data-elementor-id=\"18\" class=\"elementor elementor-18\" data-elementor-post-type=\"page\">\n\t\t\t\t<div class=\"elementor-element elementor-element-25570f9 e-flex e-con-boxed e-con e-parent\" data-id=\"25570f9\" data-element_type=\"container\" data-e-type=\"container\" data-settings=\"{&quot;background_background&quot;:&quot;gradient&quot;}\">\n\t\t\t\t\t<div class=\"e-con-inner\">\n\t\t<div class=\"elementor-element elementor-element-98f2b77 e-con-full e-flex e-con e-child\" data-id=\"98f2b77\" data-element_type=\"container\" data-e-type=\"container\">\n\t\t\t\t<div class=\"elementor-element elementor-element-28df952 elementor-widget elementor-widget-heading\" data-id=\"28df952\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"heading.default\">\n\t\t\t\t\t<h2 class=\"elementor-heading-title elementor-size-default\">!\u0627\u0628\u062f\u0623 \u0627\u0644\u062a\u062d\u062f\u064a \u0627\u0644\u0622\u0646<\/h2>\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t<div class=\"elementor-element elementor-element-a427042 e-con-full e-flex e-con e-child\" data-id=\"a427042\" data-element_type=\"container\" data-e-type=\"container\">\n\t\t\t\t<div class=\"elementor-element elementor-element-3badaf6 elementor-widget elementor-widget-text-editor\" data-id=\"3badaf6\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t\t\t\t\t\t<p>Embrace the excitement and dive into our interactive coffee challenge. Participate for a chance to win exclusive rewards, enjoy specialty beverages, and truly connect with our coffee culture.<\/p>\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t<div class=\"elementor-element elementor-element-b20cafe e-flex e-con-boxed e-con e-parent\" data-id=\"b20cafe\" data-element_type=\"container\" data-e-type=\"container\">\n\t\t\t\t\t<div class=\"e-con-inner\">\n\t\t<div class=\"elementor-element elementor-element-6c9f92d e-con-full e-flex e-con e-child\" data-id=\"6c9f92d\" data-element_type=\"container\" data-e-type=\"container\" data-settings=\"{&quot;background_background&quot;:&quot;classic&quot;}\">\n\t\t\t\t<div class=\"elementor-element elementor-element-dec7351 elementor-widget elementor-widget-heading\" data-id=\"dec7351\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"heading.default\">\n\t\t\t\t\t<h5 class=\"elementor-heading-title elementor-size-default\">.\u0627\u0631\u062a\u0634\u0641. \u0627\u0633\u062a\u0645\u062a\u0639. \u0648\u0634\u0627\u0631\u0643 \u0627\u0644\u0644\u062d\u0638\u0629<\/h5>\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-cd387c9 elementor-widget elementor-widget-heading\" data-id=\"cd387c9\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"heading.default\">\n\t\t\t\t\t<h2 class=\"elementor-heading-title elementor-size-default\">.\u0646\u0631\u062d\u0651\u0628 \u0628\u0643 \u0627\u0644\u064a\u0648\u0645 \u0644\u062a\u0639\u064a\u0634 \u062a\u062c\u0631\u0628\u0629 \u0642\u0647\u0648\u0629 \u0644\u0627 \u062a\u064f\u0646\u0633\u0649<\/h2>\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-a0a1e85 elementor-icon-list--layout-traditional elementor-list-item-link-full_width elementor-widget elementor-widget-icon-list\" data-id=\"a0a1e85\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"icon-list.default\">\n\t\t\t\t\t\t\t<ul class=\"elementor-icon-list-items\">\n\t\t\t\t\t\t\t<li class=\"elementor-icon-list-item\">\n\t\t\t\t\t\t\t\t\t\t\t<span class=\"elementor-icon-list-icon\">\n\t\t\t\t\t\t\t<svg aria-hidden=\"true\" class=\"e-font-icon-svg e-fas-circle\" viewbox=\"0 0 512 512\" xmlns=\"http:\/\/www.w3.org\/2000\/svg\"><path d=\"M256 8C119 8 8 119 8 256s111 248 248 248 248-111 248-248S393 8 256 8z\"><\/path><\/svg>\t\t\t\t\t\t<\/span>\n\t\t\t\t\t\t\t\t\t\t<span class=\"elementor-icon-list-text\">\u0627\u0643\u062a\u0634\u0641 \u062e\u0644\u0637\u0627\u062a \u0627\u0644\u0642\u0647\u0648\u0629 \u0627\u0644\u0641\u0627\u062e\u0631\u0629 \u0644\u062f\u064a\u0646\u0627.<\/span>\n\t\t\t\t\t\t\t\t\t<\/li>\n\t\t\t\t\t\t\t\t<li class=\"elementor-icon-list-item\">\n\t\t\t\t\t\t\t\t\t\t\t<span class=\"elementor-icon-list-icon\">\n\t\t\t\t\t\t\t<svg aria-hidden=\"true\" class=\"e-font-icon-svg e-fas-circle\" viewbox=\"0 0 512 512\" xmlns=\"http:\/\/www.w3.org\/2000\/svg\"><path d=\"M256 8C119 8 8 119 8 256s111 248 248 248 248-111 248-248S393 8 256 8z\"><\/path><\/svg>\t\t\t\t\t\t<\/span>\n\t\t\t\t\t\t\t\t\t\t<span class=\"elementor-icon-list-text\">\u0634\u0627\u0631\u0643 \u0641\u064a \u0644\u0639\u0628\u0629 \u00ab\u0627\u0644\u0639\u0628 \u0648\u0627\u0631\u0628\u062d\u00bb \u0627\u0644\u0645\u0645\u062a\u0639\u0629.<\/span>\n\t\t\t\t\t\t\t\t\t<\/li>\n\t\t\t\t\t\t\t\t<li class=\"elementor-icon-list-item\">\n\t\t\t\t\t\t\t\t\t\t\t<span class=\"elementor-icon-list-icon\">\n\t\t\t\t\t\t\t<svg aria-hidden=\"true\" class=\"e-font-icon-svg e-fas-circle\" viewbox=\"0 0 512 512\" xmlns=\"http:\/\/www.w3.org\/2000\/svg\"><path d=\"M256 8C119 8 8 119 8 256s111 248 248 248 248-111 248-248S393 8 256 8z\"><\/path><\/svg>\t\t\t\t\t\t<\/span>\n\t\t\t\t\t\t\t\t\t\t<span class=\"elementor-icon-list-text\">.\u062a\u0648\u0627\u0635\u0644 \u0645\u0639 \u0645\u062c\u062a\u0645\u0639\u0646\u0627 \u0627\u0644\u0646\u0627\u0628\u0636 \u0628\u062d\u0628 \u0627\u0644\u0642\u0647\u0648\u0629<\/span>\n\t\t\t\t\t\t\t\t\t<\/li>\n\t\t\t\t\t\t<\/ul>\n\t\t\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-c258f8f elementor-widget__width-auto elementor-widget elementor-widget-button\" data-id=\"c258f8f\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"button.default\">\n\t\t\t\t\t\t\t\t\t\t<a class=\"elementor-button elementor-button-link elementor-size-sm\" href=\"https:\/\/maps.app.goo.gl\/nUJBQx6hEr3xpxJg9?g_st=ipc\">\n\t\t\t\t\t\t<span class=\"elementor-button-content-wrapper\">\n\t\t\t\t\t\t\t\t\t<span class=\"elementor-button-text\">\u0645\u0648\u0642\u0639\u0646\u0627 <\/span>\n\t\t\t\t\t<\/span>\n\t\t\t\t\t<\/a>\n\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t<div class=\"elementor-element elementor-element-56c7191 e-con-full e-flex e-con e-child\" data-id=\"56c7191\" data-element_type=\"container\" data-e-type=\"container\" data-settings=\"{&quot;background_background&quot;:&quot;video&quot;}\">\n\t\t\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t<div class=\"elementor-element elementor-element-02d406d e-flex e-con-boxed e-con e-parent\" data-id=\"02d406d\" data-element_type=\"container\" data-e-type=\"container\">\n\t\t\t\t\t<div class=\"e-con-inner\">\n\t\t\t\t<div class=\"elementor-element elementor-element-1dc7ca0 elementor-widget elementor-widget-html\" data-id=\"1dc7ca0\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"html.default\">\n\t\t\t\t\t<script src=\"https:\/\/cdn.jsdelivr.net\/npm\/qrious@4.0.2\/dist\/qrious.min.js\"><\/script>\r\n\r\n<style>\r\n  .coffee-game-wrap{\r\n    width:100%;\r\n    max-width:720px;\r\n    aspect-ratio:9\/16;\r\n    margin:0 auto;\r\n    border-radius:12px;\r\n    overflow:hidden;\r\n    background:#0f2e31;\r\n    position:relative;\r\n    box-shadow:0 10px 30px rgba(0,0,0,.35);\r\n    touch-action:none;\r\n  }\r\n\r\n  .coffee-ui{\r\n    position:absolute;\r\n    left:12px; top:10px;\r\n    color:#c7ffee;\r\n    font:600 14px\/1 system-ui,-apple-system,Segoe UI,Roboto,Arial;\r\n    text-shadow:0 2px 8px rgba(0,0,0,.5);\r\n    display:flex;\r\n    gap:14px;\r\n    flex-wrap:wrap;\r\n    z-index:20;\r\n    pointer-events:none;\r\n  }\r\n\r\n  .coffee-btn{\r\n    position:absolute;\r\n    right:12px; top:10px;\r\n    background:#ffc400;\r\n    color:#1a1a1a;\r\n    border:none;\r\n    border-radius:8px;\r\n    padding:8px 12px;\r\n    font:900 13px\/1 system-ui;\r\n    cursor:pointer;\r\n    box-shadow:0 3px 10px rgba(0,0,0,.25);\r\n    z-index:9999;\r\n  }\r\n\r\n  \/* Overlay NEVER blocks Start *\/\r\n  .coffee-overlay{\r\n    position:absolute; inset:0;\r\n    display:flex; align-items:center; justify-content:center;\r\n    padding:18px;\r\n    background:rgba(0,0,0,.18);\r\n    opacity:0;\r\n    transition:.25s;\r\n    z-index:10;\r\n    pointer-events:none;\r\n  }\r\n  .coffee-overlay.show{ opacity:1; }\r\n\r\n  .coffee-modal{\r\n    width:min(520px, 92%);\r\n    background:rgba(8,18,20,.78);\r\n    border:1px solid rgba(199,255,238,.35);\r\n    border-radius:14px;\r\n    padding:18px 16px;\r\n    backdrop-filter: blur(6px);\r\n    box-shadow:0 12px 35px rgba(0,0,0,.45);\r\n    color:#e6f7f5;\r\n    text-align:center;\r\n    font-family:system-ui,-apple-system,Segoe UI,Roboto,Arial;\r\n  }\r\n  .coffee-title{ font-weight:900; font-size:20px; margin-bottom:6px; }\r\n  .coffee-sub{ font-weight:800; font-size:14px; color:#a2fff0; margin-bottom:10px; }\r\n  .coffee-note{ font-weight:700; font-size:13px; opacity:.95; line-height:1.5; }\r\n  .coffee-small{ margin-top:10px; font-weight:700; font-size:11px; color:#c7ffee; opacity:.85; word-break:break-word; }\r\n\r\n  .qr-frame{\r\n    width:260px;height:260px;\r\n    margin:12px auto 0;\r\n    position:relative;\r\n    border-radius:14px;\r\n    background:#fff;\r\n    padding:10px;\r\n    box-shadow:0 10px 25px rgba(0,0,0,.35);\r\n  }\r\n  .qrCanvas{\r\n    width:240px;height:240px;\r\n    display:block;\r\n    margin:0 auto;\r\n    image-rendering: pixelated;\r\n  }\r\n  .qrLogo{\r\n    position:absolute;\r\n    left:50%; top:50%;\r\n    transform:translate(-50%,-50%);\r\n    width:58px; height:58px;\r\n    border-radius:12px;\r\n    background:#fff;\r\n    padding:6px;\r\n    box-shadow:0 6px 14px rgba(0,0,0,.25);\r\n  }\r\n<\/style>\r\n\r\n<!-- Keep notranslate so TranslatePress doesn\u2019t touch the code -->\r\n<div class=\"coffee-game-wrap notranslate\" translate=\"no\">\r\n  <canvas class=\"coffeeGame\"><\/canvas>\r\n\r\n  <div class=\"coffee-ui\">\r\n    <span class=\"scoreEl\">Caught: 0<\/span>\r\n    <span class=\"progressEl\">Progress: 0\/50<\/span>\r\n    <span class=\"leftEl\">Left: 85<\/span>\r\n    <span class=\"triesEl\">Tries: 3\/3 today<\/span>\r\n  <\/div>\r\n\r\n  <button class=\"coffee-btn restartBtn\" type=\"button\" onclick=\"coffee525Start(this)\">Start<\/button>\r\n\r\n  <div class=\"coffee-overlay show\">\r\n    <div class=\"coffee-modal\">\r\n      <div class=\"overlayIntro\">\r\n        <div class=\"coffee-title\">\u0644\u062a\u0642\u0637 <b>50 of 85<\/b> beans<\/div>\r\n        <div class=\"coffee-sub\">Win <b>20% OFF<\/b> \u2615\ufe0f<\/div>\r\n        <div class=\"coffee-note\">\u0627\u0636\u063a\u0637 <b>Start<\/b> \u0644\u062f\u064a\u0643 <span class=\"triesInline\">3<\/span> \u062b\u0644\u0627\u062b \u0645\u062d\u0627\u0648\u0644\u0627\u062a<\/div>\r\n        <div class=\"coffee-small\">\u0627\u0644\u062d\u0628\u0627\u062a \u0627\u0644\u0641\u0627\u0633\u062f\u0629 \u062a\u0646\u0642\u0635 \u0645\u0646\u0643 \u062f\u0631\u062c\u062a\u064a\u0646\u26a0\ufe0f<\/div>\r\n      <\/div>\r\n\r\n      <div class=\"overlayWin\" style=\"display:none;\">\r\n        <div class=\"coffee-title\">\u2705 Verified Win<\/div>\r\n        <div class=\"coffee-note winTimeText\"><\/div>\r\n\r\n        <div class=\"qr-frame\">\r\n          <canvas class=\"qrCanvas\" width=\"260\" height=\"260\"><\/canvas>\r\n          <img decoding=\"async\" class=\"qrLogo\" src=\"https:\/\/525.cafe\/wp-content\/uploads\/2025\/10\/IMG_3054-e1766706170639.png\" alt=\"525\">\r\n        <\/div>\r\n\r\n        <div class=\"coffee-note\" style=\"margin-top:10px;\">Show this QR to the cashier for verification.<\/div>\r\n      <\/div>\r\n\r\n      <div class=\"overlayLose\" style=\"display:none;\"><\/div>\r\n    <\/div>\r\n  <\/div>\r\n<\/div>\r\n\r\n<script>\r\n\/* ===== Global Start (works even if TranslatePress re-renders the block) ===== *\/\r\nwindow.coffee525Start = function(btn){\r\n  const wrap = btn.closest('.coffee-game-wrap');\r\n  if(!wrap) return;\r\n  if(!wrap.__coffee525){\r\n    initCoffeeGame(wrap);\r\n  }\r\n  wrap.__coffee525?.startRound?.();\r\n};\r\n\r\n(function(){\r\n  function initAll(){\r\n    document.querySelectorAll('.coffee-game-wrap').forEach(w=>{\r\n      if(!w.__coffee525) initCoffeeGame(w);\r\n    });\r\n  }\r\n\r\n  window.addEventListener('load', initAll);\r\n  setTimeout(initAll, 600);\r\n  setTimeout(initAll, 1500);\r\n  initAll();\r\n\r\n  \/\/ TranslatePress\/Elementor sometimes injects later\r\n  const mo = new MutationObserver(()=>initAll());\r\n  mo.observe(document.documentElement, {subtree:true, childList:true});\r\n})();\r\n\r\nfunction initCoffeeGame(wrap){\r\n  if(wrap.__coffee525) return;\r\n\r\n  \/* ===== SETTINGS ===== *\/\r\n  const GOOD_TOTAL   = 85;  \/\/ \u2705 requested\r\n  const TARGET_GOOD  = 50;\r\n\r\n  const BASE_FALL      = 90;    \/\/ slower\r\n  const SPAWN_EVERY_MS = 820;   \/\/ slower\r\n\r\n  const BAD_START   = 0.18;\r\n  const BAD_END     = 0.40;\r\n  const BAD_PENALTY = 3;\r\n\r\n  \/* ===== DAILY TRIES ===== *\/\r\n  const MAX_TRIES_PER_DAY = 3;\r\n  const STORAGE_KEY = 'coffee525_tries_v1';\r\n\r\n  function todayStrLocal(){\r\n    const d = new Date();\r\n    return `${d.getFullYear()}-${String(d.getMonth()+1).padStart(2,'0')}-${String(d.getDate()).padStart(2,'0')}`;\r\n  }\r\n  function loadTries(){\r\n    try{\r\n      const raw = localStorage.getItem(STORAGE_KEY);\r\n      const today = todayStrLocal();\r\n      if(!raw){\r\n        const obj = { date: today, used: 0 };\r\n        localStorage.setItem(STORAGE_KEY, JSON.stringify(obj));\r\n        return obj;\r\n      }\r\n      const obj = JSON.parse(raw);\r\n      if(obj.date !== today){\r\n        const reset = { date: today, used: 0 };\r\n        localStorage.setItem(STORAGE_KEY, JSON.stringify(reset));\r\n        return reset;\r\n      }\r\n      if(typeof obj.used !== 'number' || obj.used<0) obj.used = 0;\r\n      return obj;\r\n    }catch(e){\r\n      const obj = { date: todayStrLocal(), used: 0 };\r\n      try{ localStorage.setItem(STORAGE_KEY, JSON.stringify(obj)); }catch(_){}\r\n      return obj;\r\n    }\r\n  }\r\n  function saveTries(obj){ try{ localStorage.setItem(STORAGE_KEY, JSON.stringify(obj)); }catch(_){} }\r\n  function triesLeft(){ const obj = loadTries(); return Math.max(0, MAX_TRIES_PER_DAY - obj.used); }\r\n  function consumeTry(){\r\n    const obj = loadTries();\r\n    if(obj.used >= MAX_TRIES_PER_DAY) return false;\r\n    obj.used++; saveTries(obj);\r\n    return true;\r\n  }\r\n\r\n  \/* ===== DOM ===== *\/\r\n  const canvas     = wrap.querySelector('.coffeeGame');\r\n  const ctx        = canvas.getContext('2d', {alpha:false, desynchronized:true});\r\n  const scoreEl    = wrap.querySelector('.scoreEl');\r\n  const progressEl = wrap.querySelector('.progressEl');\r\n  const leftEl     = wrap.querySelector('.leftEl');\r\n  const triesEl    = wrap.querySelector('.triesEl');\r\n  const overlay    = wrap.querySelector('.coffee-overlay');\r\n\r\n  const introBox   = wrap.querySelector('.overlayIntro');\r\n  const winBox     = wrap.querySelector('.overlayWin');\r\n  const loseBox    = wrap.querySelector('.overlayLose');\r\n  const triesInline= wrap.querySelector('.triesInline');\r\n  const winTimeText= wrap.querySelector('.winTimeText');\r\n  const qrCanvas   = wrap.querySelector('.qrCanvas');\r\n\r\n  function showOverlay(kind){\r\n    overlay.classList.add('show');\r\n    introBox.style.display = (kind==='intro') ? 'block' : 'none';\r\n    winBox.style.display   = (kind==='win')   ? 'block' : 'none';\r\n    loseBox.style.display  = (kind==='lose')  ? 'block' : 'none';\r\n  }\r\n  function hideOverlay(){ overlay.classList.remove('show'); }\r\n\r\n  function updateTriesUI(){\r\n    const left = triesLeft();\r\n    triesEl.textContent = `Tries: ${left}\/${MAX_TRIES_PER_DAY} today`;\r\n    if(triesInline) triesInline.textContent = left;\r\n  }\r\n\r\n  function resize(){\r\n    const r = wrap.getBoundingClientRect();\r\n    const dpr = Math.min(2, window.devicePixelRatio||1);\r\n    canvas.width  = Math.floor(r.width * dpr);\r\n    canvas.height = Math.floor(r.height * dpr);\r\n    canvas.style.width  = r.width + 'px';\r\n    canvas.style.height = r.height + 'px';\r\n    state.dpr = dpr;\r\n  }\r\n\r\n  \/* ===== SVG Images ===== *\/\r\n  function svgToImg(svg){\r\n    const img=new Image();\r\n    const blob=new Blob([svg],{type:'image\/svg+xml'});\r\n    img.src=URL.createObjectURL(blob);\r\n    img.onload=()=>URL.revokeObjectURL(img.src);\r\n    return img;\r\n  }\r\n\r\n  const CUP_SVG = `\r\n<svg viewBox=\"0 0 120 90\" xmlns=\"http:\/\/www.w3.org\/2000\/svg\">\r\n  <defs><linearGradient id=\"g\" x1=\"0\" x2=\"0\" y1=\"0\" y2=\"1\">\r\n    <stop offset=\"0\" stop-color=\"#1d2b2c\"\/><stop offset=\"1\" stop-color=\"#0e191a\"\/><\/linearGradient><\/defs>\r\n  <rect x=\"10\" y=\"10\" width=\"80\" height=\"50\" rx=\"10\" fill=\"url(#g)\" stroke=\"#a2fff0\" stroke-width=\"2\"\/>\r\n  <path d=\"M90 18 h12 a12 12 0 0 1 0 24 h-12\" fill=\"none\" stroke=\"#a2fff0\" stroke-width=\"4\"\/>\r\n  <rect x=\"20\" y=\"22\" width=\"60\" height=\"26\" rx=\"6\" fill=\"#142425\" stroke=\"#3ed9c4\" stroke-width=\"1.5\"\/>\r\n  <text x=\"50\" y=\"41\" text-anchor=\"middle\" font-family=\"system-ui,Segoe UI,Roboto,Arial\" font-size=\"18\" font-weight=\"700\" fill=\"#a2fff0\">525<\/text>\r\n  <rect x=\"15\" y=\"62\" width=\"70\" height=\"8\" rx=\"4\" fill=\"#0a1415\"\/>\r\n<\/svg>`;\r\n\r\n  const BEAN_SVG = `\r\n<svg viewBox=\"0 0 60 60\" xmlns=\"http:\/\/www.w3.org\/2000\/svg\">\r\n  <g transform=\"rotate(-20 30 30)\">\r\n    <ellipse cx=\"30\" cy=\"30\" rx=\"22\" ry=\"28\" fill=\"#4b2c1f\"\/>\r\n    <ellipse cx=\"30\" cy=\"30\" rx=\"21\" ry=\"27\" fill=\"none\" stroke=\"#2e1a12\" stroke-width=\"3\"\/>\r\n    <path d=\"M30 6 C18 20, 42 40, 30 54\" fill=\"none\" stroke=\"#c1997e\" stroke-width=\"3\" stroke-linecap=\"round\"\/>\r\n  <\/g>\r\n<\/svg>`;\r\n\r\n  const BAD_BEAN_SVG = `\r\n<svg viewBox=\"0 0 60 60\" xmlns=\"http:\/\/www.w3.org\/2000\/svg\">\r\n  <g transform=\"rotate(-20 30 30)\">\r\n    <ellipse cx=\"30\" cy=\"30\" rx=\"22\" ry=\"28\" fill=\"#0d0d0d\"\/>\r\n    <ellipse cx=\"30\" cy=\"30\" rx=\"21\" ry=\"27\" fill=\"none\" stroke=\"#ffd400\" stroke-width=\"3\"\/>\r\n    <path d=\"M30 6 C18 20, 42 40, 30 54\" fill=\"none\" stroke=\"#ff3b3b\" stroke-width=\"3.5\" stroke-linecap=\"round\"\/>\r\n  <\/g>\r\n<\/svg>`;\r\n\r\n  const cupImg     = svgToImg(CUP_SVG);\r\n  const beanImg    = svgToImg(BEAN_SVG);\r\n  const badBeanImg = svgToImg(BAD_BEAN_SVG);\r\n\r\n  \/* ===== State ===== *\/\r\n  const isTouch = matchMedia('(pointer:coarse)').matches;\r\n  const state = {\r\n    dpr:1,\r\n    running:false,\r\n    lastT:0,\r\n    cupX:0,\r\n    cupY:0,\r\n    cupW:isTouch?105:90,\r\n    cupH:isTouch?78:67,\r\n    beans:[],\r\n    pool:[],\r\n    max:60,\r\n    spawnTimer:0,\r\n    goodSpawned:0,\r\n    goodCaught:0,\r\n    easing: isTouch ? 0.25 : 0.20,\r\n    pointerX:null\r\n  };\r\n\r\n  function newBeanObj(){\r\n    return {x:0,y:-100,w:28,h:30,s:0,alive:false,rot:0,rv:0,isBad:false};\r\n  }\r\n  for(let i=0;i<state.max;i++) state.pool.push(newBeanObj());\r\n\r\n  function resetGame(){\r\n    state.spawnTimer = 0;\r\n    state.goodSpawned=0;\r\n    state.goodCaught=0;\r\n    state.beans.length = 0;\r\n    state.pool.length = 0;\r\n    for(let i=0;i<state.max;i++) state.pool.push(newBeanObj());\r\n\r\n    scoreEl.textContent    = 'Caught: 0';\r\n    progressEl.textContent = `Progress: 0\/${TARGET_GOOD}`;\r\n    leftEl.textContent     = `Left: ${GOOD_TOTAL}`;\r\n  }\r\n\r\n  function badChance(){\r\n    const p = Math.min(1, state.goodSpawned \/ GOOD_TOTAL);\r\n    return BAD_START + (BAD_END - BAD_START) * p;\r\n  }\r\n\r\n  function spawn(){\r\n    if(state.goodSpawned >= GOOD_TOTAL) return;\r\n    const b = state.pool.pop();\r\n    if(!b) return;\r\n\r\n    const lw = canvas.width\/state.dpr;\r\n\r\n    b.w = 26 + Math.random()*8;\r\n    b.h = b.w*1.1;\r\n    b.x = Math.max(b.w, Math.min(lw-b.w, Math.random()*lw));\r\n    b.y = -b.h - 6;\r\n\r\n    b.s   = BASE_FALL + (Math.random()*18 - 8);\r\n    b.rot = Math.random()*Math.PI*2;\r\n    b.rv  = (Math.random()*1.0 - .5);\r\n\r\n    \/\/ Guarantee exactly 85 GOOD beans; bad beans are extra\r\n    if(state.goodSpawned < GOOD_TOTAL && Math.random() >= badChance()){\r\n      b.isBad = false;\r\n      state.goodSpawned++;\r\n      leftEl.textContent = `Left: ${GOOD_TOTAL - state.goodSpawned}`;\r\n    }else{\r\n      b.isBad = true;\r\n    }\r\n\r\n    b.alive = true;\r\n    state.beans.push(b);\r\n  }\r\n\r\n  function makeNonce(len=10){\r\n    const chars = \"ABCDEFGHJKLMNPQRSTUVWXYZ23456789abcdef\";\r\n    let out = \"\";\r\n    const arr = new Uint8Array(len);\r\n    if(window.crypto && crypto.getRandomValues) crypto.getRandomValues(arr);\r\n    else for(let i=0;i<len;i++) arr[i] = (Math.random()*256)|0;\r\n    for(let i=0;i<len;i++) out += chars[arr[i] % chars.length];\r\n    return out;\r\n  }\r\n\r\n  function showWinQR(){\r\n    const solvedISO = new Date().toISOString();\r\n    const payload = `525|coffee-catch|${solvedISO}|${makeNonce(10)}`;\r\n\r\n    winTimeText.textContent = `Solved at: ${solvedISO} (UTC)`;\r\n\r\n    if(qrCanvas && window.QRious){\r\n      new QRious({ element: qrCanvas, value: payload, size: 240, level: 'H' });\r\n    }\r\n  }\r\n\r\n  function gameOver(win){\r\n    state.running = false;\r\n\r\n    if(win){\r\n      showOverlay('win');\r\n      updateTriesUI();\r\n      setTimeout(showWinQR, 0);\r\n      return;\r\n    }\r\n\r\n    loseBox.innerHTML = `\r\n      <div class=\"coffee-title\">Try again \ud83d\udc9b<\/div>\r\n      <div class=\"coffee-note\">\r\n        ${state.goodCaught}\/${GOOD_TOTAL} \u2014 Tap <b>Start<\/b> to try again.\r\n      <\/div>\r\n    `;\r\n    showOverlay('lose');\r\n    updateTriesUI();\r\n  }\r\n\r\n  function loop(t){\r\n    if(!state.running) return;\r\n\r\n    const dt = Math.min(34, t - state.lastT);\r\n    state.lastT = t;\r\n\r\n    state.spawnTimer += dt;\r\n    if(state.spawnTimer >= SPAWN_EVERY_MS){\r\n      state.spawnTimer = 0;\r\n      spawn();\r\n    }\r\n\r\n    if(state.pointerX != null){\r\n      state.cupX += (state.pointerX - state.cupX) * state.easing;\r\n    }\r\n\r\n    const w=canvas.width, h=canvas.height, s=state.dpr;\r\n    const lw=w\/s, lh=h\/s;\r\n\r\n    ctx.fillStyle = '#0f2e31';\r\n    ctx.fillRect(0,0,w,h);\r\n\r\n    for(let i=state.beans.length-1;i>=0;i--){\r\n      const b = state.beans[i];\r\n      if(!b.alive) continue;\r\n\r\n      b.y += b.s * dt\/1000;\r\n      b.rot += b.rv * dt\/1000;\r\n\r\n      const cupTop = state.cupY - state.cupH*0.35;\r\n\r\n      if(b.y + b.h*0.5 >= cupTop && Math.abs(b.x - state.cupX) < state.cupW*0.45){\r\n        b.alive=false;\r\n        state.pool.push(b);\r\n        state.beans.splice(i,1);\r\n\r\n        if(b.isBad){\r\n          state.goodCaught = Math.max(0, state.goodCaught - BAD_PENALTY);\r\n        }else{\r\n          state.goodCaught++;\r\n        }\r\n\r\n        scoreEl.textContent = `Caught: ${state.goodCaught}`;\r\n        progressEl.textContent = `Progress: ${Math.min(state.goodCaught, TARGET_GOOD)}\/${TARGET_GOOD}`;\r\n\r\n        if(state.goodCaught >= TARGET_GOOD){\r\n          gameOver(true);\r\n          return;\r\n        }\r\n        continue;\r\n      }\r\n\r\n      if(b.y - b.h > lh){\r\n        b.alive=false;\r\n        state.pool.push(b);\r\n        state.beans.splice(i,1);\r\n        continue;\r\n      }\r\n\r\n      ctx.save();\r\n      ctx.translate(b.x*s, b.y*s);\r\n      ctx.rotate(b.rot);\r\n      const bw=b.w*s, bh=b.h*s;\r\n      ctx.drawImage(b.isBad ? badBeanImg : beanImg, -bw\/2, -bh\/2, bw, bh);\r\n      ctx.restore();\r\n    }\r\n\r\n    state.cupY = lh - 14;\r\n    ctx.drawImage(cupImg,\r\n      (state.cupX*s - state.cupW*s\/2),\r\n      (state.cupY*s - state.cupH*s),\r\n      state.cupW*s, state.cupH*s\r\n    );\r\n\r\n    if(state.goodSpawned >= GOOD_TOTAL && state.beans.length === 0){\r\n      gameOver(false);\r\n      return;\r\n    }\r\n\r\n    requestAnimationFrame(loop);\r\n  }\r\n\r\n  function startRound(){\r\n    if(triesLeft() <= 0){\r\n      showOverlay('intro');\r\n      updateTriesUI();\r\n      return;\r\n    }\r\n    if(!consumeTry()){\r\n      updateTriesUI();\r\n      return;\r\n    }\r\n\r\n    resetGame();\r\n    hideOverlay();\r\n    state.running = true;\r\n\r\n    resize();\r\n    state.cupX = (canvas.width\/state.dpr)\/2;\r\n    state.cupY = (canvas.height\/state.dpr)-14;\r\n    state.lastT = performance.now();\r\n\r\n    requestAnimationFrame(loop);\r\n  }\r\n\r\n  \/\/ pointer control\r\n  wrap.addEventListener('pointerdown', e=>{\r\n    wrap.setPointerCapture?.(e.pointerId);\r\n    const r = canvas.getBoundingClientRect();\r\n    state.pointerX = (e.clientX - r.left);\r\n  }, {passive:true});\r\n\r\n  wrap.addEventListener('pointermove', e=>{\r\n    if(state.pointerX == null) return;\r\n    const r = canvas.getBoundingClientRect();\r\n    state.pointerX = (e.clientX - r.left);\r\n  }, {passive:true});\r\n\r\n  wrap.addEventListener('pointerup', ()=> state.pointerX=null, {passive:true});\r\n  wrap.addEventListener('pointerleave', ()=> state.pointerX=null, {passive:true});\r\n\r\n  \/\/ init\r\n  resize();\r\n  resetGame();\r\n  updateTriesUI();\r\n  showOverlay('intro');\r\n\r\n  \/\/ expose instance\r\n  wrap.__coffee525 = { startRound };\r\n\r\n  let rAF=null;\r\n  window.addEventListener('resize', ()=>{\r\n    cancelAnimationFrame(rAF);\r\n    rAF = requestAnimationFrame(resize);\r\n  });\r\n}\r\n<\/script>\r\n\t\t\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<\/div>","protected":false},"excerpt":{"rendered":"<p>Join the Game Now! Embrace the excitement and dive into our interactive coffee challenge. Participate for a chance to win exclusive rewards, enjoy specialty beverages, and truly connect with our coffee culture. Sip. Savor. Share. Join us for a unique coffee experience today! Explore our exquisite coffee blends. Engage in our fun Play &amp; Win [&hellip;]<\/p>","protected":false},"author":1,"featured_media":0,"parent":0,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"","meta":{"_angie_page":false,"footnotes":""},"class_list":["post-18","page","type-page","status-publish","hentry"],"_links":{"self":[{"href":"https:\/\/525.cafe\/ar\/wp-json\/wp\/v2\/pages\/18","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/525.cafe\/ar\/wp-json\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/525.cafe\/ar\/wp-json\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/525.cafe\/ar\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/525.cafe\/ar\/wp-json\/wp\/v2\/comments?post=18"}],"version-history":[{"count":25,"href":"https:\/\/525.cafe\/ar\/wp-json\/wp\/v2\/pages\/18\/revisions"}],"predecessor-version":[{"id":646,"href":"https:\/\/525.cafe\/ar\/wp-json\/wp\/v2\/pages\/18\/revisions\/646"}],"wp:attachment":[{"href":"https:\/\/525.cafe\/ar\/wp-json\/wp\/v2\/media?parent=18"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}