{"id":8,"date":"2026-04-19T18:20:53","date_gmt":"2026-04-19T18:20:53","guid":{"rendered":"http:\/\/sweetandnaughty.co.uk\/?page_id=8"},"modified":"2026-04-19T18:47:24","modified_gmt":"2026-04-19T18:47:24","slug":"8-2","status":"publish","type":"page","link":"https:\/\/sweetandnaughty.co.uk\/","title":{"rendered":"Landing Page"},"content":{"rendered":"\n<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n  <meta charset=\"UTF-8\" \/>\n  <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\" \/>\n  <title>Candy Hero<\/title>\n  <style>\n    * { margin: 0; padding: 0; box-sizing: border-box; }\n    body,:root {\n      background: #000; \n      overflow: hidden; \n      height:100%!important;\n      width:100%!important;\n      margin:0;\n    }\n    #heroCanvas {\n      display: block;\n      width: 100%;\n      height: 100%;\n      cursor: crosshair;\n    }\n    main {\n      margin:0!important;\n    }\n    #hint {\n      position: fixed;\n      bottom: 16px;\n      right: 18px;\n      font-family: sans-serif;\n      font-size: 12px;\n      color: rgba(255,255,255,0.3);\n      pointer-events: none;\n    }\n  <\/style>\n<\/head>\n<body>\n  <canvas id=\"heroCanvas\"><\/canvas>\n  <script>\n    (function () {\n      const canvas = document.getElementById('heroCanvas');\n      const ctx = canvas.getContext('2d');\n\n      \/* \u2500\u2500 Resize \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 *\/\n      function resize() {\n        canvas.width  = window.innerWidth;\n        canvas.height = window.innerHeight;\n      }\n      resize();\n      window.addEventListener('resize', resize);\n\n      \/* \u2500\u2500 Palette \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 *\/\n      const COLORS = [\n        '#FF6B6B','#FF9F43','#FECA57','#48DBFB','#FF9FF3',\n        '#54A0FF','#A29BFE','#00CEC9','#FD79A8','#6C5CE7',\n        '#00B894','#E17055'\n      ];\n\n      \/* \u2500\u2500 Sweet drawers \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 *\/\n      function drawLollipop(c, x, y, sz, col, ang) {\n        c.save(); c.translate(x, y); c.rotate(ang);\n        \/\/ Stick\n        c.strokeStyle = '#C8A96E'; c.lineWidth = sz * 0.13; c.lineCap = 'round';\n        c.beginPath(); c.moveTo(0, sz * 0.55); c.lineTo(0, sz * 1.5); c.stroke();\n        \/\/ Ball\n        c.fillStyle = col;\n        c.beginPath(); c.arc(0, 0, sz * 0.6, 0, Math.PI * 2); c.fill();\n        \/\/ Shine arc\n        c.strokeStyle = 'rgba(255,255,255,0.45)'; c.lineWidth = sz * 0.1;\n        c.beginPath(); c.arc(0, 0, sz * 0.32, 0.2, Math.PI * 1.6); c.stroke();\n        \/\/ Specular dot\n        c.fillStyle = 'rgba(255,255,255,0.35)';\n        c.beginPath(); c.arc(-sz * 0.18, -sz * 0.18, sz * 0.16, 0, Math.PI * 2); c.fill();\n        c.restore();\n      }\n\n      function drawWrapped(c, x, y, sz, col, ang) {\n        c.save(); c.translate(x, y); c.rotate(ang);\n        \/\/ Body\n        c.fillStyle = col;\n        c.beginPath(); c.ellipse(0, 0, sz * 0.75, sz * 0.42, 0, 0, Math.PI * 2); c.fill();\n        \/\/ Twisted wrapper ends\n        [[-sz * 0.75, -1], [sz * 0.75, 1]].forEach(([bx, dir]) => {\n          c.fillStyle = 'rgba(255,255,255,0.75)';\n          c.beginPath();\n          c.moveTo(bx, -sz * 0.42);\n          c.lineTo(bx + dir * sz * 0.28, -sz * 0.1);\n          c.lineTo(bx + dir * sz * 0.28,  sz * 0.1);\n          c.lineTo(bx,  sz * 0.42);\n          c.closePath(); c.fill();\n        });\n        \/\/ Stripes\n        c.strokeStyle = 'rgba(255,255,255,0.4)'; c.lineWidth = sz * 0.09;\n        [-sz * 0.28, 0, sz * 0.28].forEach(lx => {\n          c.beginPath(); c.moveTo(lx, -sz * 0.42); c.lineTo(lx, sz * 0.42); c.stroke();\n        });\n        c.restore();\n      }\n\n      function drawSwirl(c, x, y, sz, col, ang) {\n        c.save(); c.translate(x, y);\n        \/\/ Disc\n        c.fillStyle = col;\n        c.beginPath(); c.arc(0, 0, sz * 0.6, 0, Math.PI * 2); c.fill();\n        \/\/ Spiral\n        c.strokeStyle = 'rgba(255,255,255,0.55)'; c.lineWidth = sz * 0.1; c.lineCap = 'round';\n        c.beginPath();\n        for (let i = 0; i < 48; i++) {\n          const a = (i \/ 48) * Math.PI * 3.5 + ang;\n          const r = (i \/ 48) * sz * 0.5;\n          const px = Math.cos(a) * r, py = Math.sin(a) * r;\n          i === 0 ? c.moveTo(px, py) : c.lineTo(px, py);\n        }\n        c.stroke();\n        \/\/ Specular\n        c.fillStyle = 'rgba(255,255,255,0.3)';\n        c.beginPath(); c.arc(-sz * 0.2, -sz * 0.2, sz * 0.14, 0, Math.PI * 2); c.fill();\n        c.restore();\n      }\n\n      function drawHeart(c, x, y, sz, col, ang) {\n        c.save(); c.translate(x, y); c.rotate(ang); c.scale(sz * 0.035, sz * 0.035);\n        c.fillStyle = col;\n        c.beginPath();\n        c.moveTo(0, 6);\n        c.bezierCurveTo(-2,  3, -8,  3, -8, -1);\n        c.bezierCurveTo(-8, -5, -4, -8,  0, -5);\n        c.bezierCurveTo( 4, -8,  8, -5,  8, -1);\n        c.bezierCurveTo( 8,  3,  2,  3,  0,  6);\n        c.fill();\n        c.restore();\n      }\n\n      const DRAWERS = [drawLollipop, drawWrapped, drawSwirl, drawHeart];\n\n      \/* \u2500\u2500 Sweet class \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 *\/\n      class Sweet {\n        constructor(x, y, burst = false) {\n          this.x    = x ?? Math.random() * canvas.width;\n          this.y    = y ?? Math.random() * canvas.height;\n          this.sz   = 9 + Math.random() * 14;\n          this.col  = COLORS[Math.floor(Math.random() * COLORS.length)];\n          this.type = Math.floor(Math.random() * DRAWERS.length);\n          this.ang  = Math.random() * Math.PI * 2;\n          this.rotSpd = (Math.random() - 0.5) * 0.04;\n          this.burst  = burst;\n\n          if (burst) {\n            const spd = 1.5 + Math.random() * 3.5;\n            const dir = Math.random() * Math.PI * 2;\n            this.vx   = Math.cos(dir) * spd;\n            this.vy   = Math.sin(dir) * spd - 1.5;\n            this.life = 1;\n            this.fade = 0.007 + Math.random() * 0.009;\n          } else {\n            const spd = 0.25 + Math.random() * 0.6;\n            const dir = Math.random() * Math.PI * 2;\n            this.vx = Math.cos(dir) * spd;\n            this.vy = Math.sin(dir) * spd;\n          }\n        }\n\n        update() {\n          this.x += this.vx;\n          this.y += this.vy;\n          this.ang += this.rotSpd;\n\n          if (this.burst) {\n            this.vy   += 0.06;   \/\/ gravity\n            this.life -= this.fade;\n            return this.life > 0;\n          } else {\n            \/\/ Wrap around edges\n            const m = this.sz * 1.5;\n            if (this.x < -m)              this.x = canvas.width  + m;\n            if (this.x > canvas.width  + m) this.x = -m;\n            if (this.y < -m)              this.y = canvas.height + m;\n            if (this.y > canvas.height + m) this.y = -m;\n            return true;\n          }\n        }\n\n        draw(c) {\n          c.globalAlpha = this.burst ? Math.max(0, this.life) : 0.88;\n          DRAWERS[this.type](c, this.x, this.y, this.sz, this.col, this.ang);\n          c.globalAlpha = 1;\n        }\n      }\n\n      \/* \u2500\u2500 Init ambient sweets \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 *\/\n      const ambient = [];\n      const bursts  = [];\n\n      for (let i = 0; i < 20; i++) ambient.push(new Sweet());\n\n      \/* \u2500\u2500 Spawn burst on interaction \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 *\/\n      function spawnBurst(x, y) {\n        const n = 10 + Math.floor(Math.random() * 6);\n        for (let i = 0; i < n; i++) bursts.push(new Sweet(x, y, true));\n      }\n\n      canvas.addEventListener('click', e => {\n        spawnBurst(e.clientX, e.clientY);\n      });\n\n      canvas.addEventListener('touchstart', e => {\n        e.preventDefault();\n        const t = e.touches[0];\n        spawnBurst(t.clientX, t.clientY);\n      }, { passive: false });\n\n      \/* \u2500\u2500 Logo image (optional) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 *\/\n      \/\/ To use your own logo, uncomment and set the path below.\n      \/\/ The image will be drawn centred over the vignette.\n      \/\/\n      const logo = new Image();\n      logo.src = '\/wp-content\/uploads\/2026\/04\/SANLogo.png';\n\n      \/* \u2500\u2500 Animation loop \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 *\/\n      function loop() {\n        \/\/ Black background\n        ctx.fillStyle = '#000';\n        ctx.fillRect(0, 0, canvas.width, canvas.height);\n\n        \/\/ Ambient sweets\n        ambient.forEach(s => { s.update(); s.draw(ctx); });\n\n        \/\/ Burst sweets\n        for (let i = bursts.length - 1; i >= 0; i--) {\n          if (!bursts[i].update()) bursts.splice(i, 1);\n          else bursts[i].draw(ctx);\n        }\n\n        \/* \u2500\u2500 Logo area \u2500\u2500 *\/\n        const cx = canvas.width  \/ 2;\n        const cy = canvas.height \/ 2;\n\n        \/\/ Soft radial vignette behind logo\n        const grd = ctx.createRadialGradient(cx, cy, 30, cx, cy, 130);\n        grd.addColorStop(0, 'rgba(0,0,0,0.75)');\n        grd.addColorStop(1, 'rgba(0,0,0,0)');\n        ctx.fillStyle = grd;\n        ctx.beginPath();\n        ctx.ellipse(cx, cy, 130, 80, 0, 0, Math.PI * 2);\n        ctx.fill();\n\n\n\n        \/\/ \u2500\u2500 Option B: image logo (uncomment after setting logo.src above) \u2500\u2500\n        if (logo.complete && logo.naturalWidth) {\n          const logoW = Math.min(window.innerWidth * 0.70, 800);\n          const logoH = logo.naturalHeight * (logoW \/ logo.naturalWidth);\n          ctx.drawImage(logo, cx - logoW \/ 2, cy - logoH \/ 1.5, logoW, logoH);\n        }\n\n        requestAnimationFrame(loop);\n      }\n\n      loop();\n    })();\n  <\/script>\n<\/body>\n<\/html>\n","protected":false},"excerpt":{"rendered":"<p>Candy Hero<\/p>\n","protected":false},"author":1,"featured_media":0,"parent":0,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"landing","meta":{"footnotes":""},"class_list":["post-8","page","type-page","status-publish","hentry"],"_links":{"self":[{"href":"https:\/\/sweetandnaughty.co.uk\/index.php\/wp-json\/wp\/v2\/pages\/8","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/sweetandnaughty.co.uk\/index.php\/wp-json\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/sweetandnaughty.co.uk\/index.php\/wp-json\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/sweetandnaughty.co.uk\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/sweetandnaughty.co.uk\/index.php\/wp-json\/wp\/v2\/comments?post=8"}],"version-history":[{"count":21,"href":"https:\/\/sweetandnaughty.co.uk\/index.php\/wp-json\/wp\/v2\/pages\/8\/revisions"}],"predecessor-version":[{"id":34,"href":"https:\/\/sweetandnaughty.co.uk\/index.php\/wp-json\/wp\/v2\/pages\/8\/revisions\/34"}],"wp:attachment":[{"href":"https:\/\/sweetandnaughty.co.uk\/index.php\/wp-json\/wp\/v2\/media?parent=8"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}