{"id":22,"date":"2026-06-06T11:05:28","date_gmt":"2026-06-06T11:05:28","guid":{"rendered":"https:\/\/affordableepoxyflooring.com.au\/?page_id=22"},"modified":"2026-06-09T16:10:02","modified_gmt":"2026-06-09T16:10:02","slug":"home-2","status":"publish","type":"page","link":"https:\/\/affordableepoxyflooring.com.au\/","title":{"rendered":"Home"},"content":{"rendered":"\t\t<div data-elementor-type=\"wp-page\" data-elementor-id=\"22\" class=\"elementor elementor-22\">\n\t\t\t\t<div class=\"elementor-element elementor-element-7b1dbc7 e-con e-atomic-element e-flexbox-base e-e5a101c \" data-id=\"7b1dbc7\" data-element_type=\"e-flexbox\" data-e-type=\"e-flexbox\" data-interaction-id=\"7b1dbc7\">\n    \t\t<div class=\"elementor-element elementor-element-ee83111 elementor-widget elementor-widget-html\" data-id=\"ee83111\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"html.default\">\n\t\t\t\t\t<!DOCTYPE html>\r\n<html lang=\"en\">\r\n<head>\r\n  <meta charset=\"UTF-8\">\r\n  <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\r\n  <title>Brisbane Epoxy Flooring Visualizer<\/title>\r\n  <style>\r\n    :root {\r\n      --ink: #0f1114;\r\n      --muted: #667085;\r\n      --line: #d9dee5;\r\n      --paper: #ffffff;\r\n      --soft: #f2f5f8;\r\n      --charcoal: #1a1d20;\r\n      --steel: #52616b;\r\n      --gold: #c7a15a;\r\n      --gold-light: #e8c87a;\r\n      --green: #24795a;\r\n      --focus: #2f6fed;\r\n      \/* Shiny\/gloss additions *\/\r\n      --gloss-hi: rgba(255,255,255,0.72);\r\n      --gloss-mid: rgba(255,255,255,0.28);\r\n      --gloss-lo: rgba(255,255,255,0.08);\r\n    }\r\n\r\n    * { box-sizing: border-box; }\r\n    html { scroll-behavior: smooth; }\r\n\r\n    body {\r\n      margin: 0;\r\n      font-family: Inter, ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, \"Segoe UI\", sans-serif;\r\n      color: var(--ink);\r\n      background: var(--paper);\r\n      letter-spacing: 0;\r\n    }\r\n\r\n    a { color: inherit; text-decoration: none; }\r\n    button, input, select { font: inherit; }\r\n    button { border: 0; cursor: pointer; }\r\n\r\n    \/* \u2500\u2500 Topbar \u2500\u2500 *\/\r\n    .topbar {\r\n      background: linear-gradient(90deg, #141618 0%, #2a2d2f 50%, #141618 100%);\r\n      color: #eef1f3;\r\n      font-size: 0.78rem;\r\n      text-align: center;\r\n      padding: 0.58rem 1rem;\r\n      letter-spacing: 0.02em;\r\n      border-bottom: 1px solid rgba(255,255,255,0.08);\r\n    }\r\n\r\n    \/* \u2500\u2500 Site Header \u2500\u2500 *\/\r\n    .site-header {\r\n      position: sticky;\r\n      top: 0;\r\n      z-index: 20;\r\n      background: rgba(255,255,255,0.82);\r\n      border-bottom: 1px solid rgba(255,255,255,0.65);\r\n      backdrop-filter: blur(28px) saturate(1.6);\r\n      -webkit-backdrop-filter: blur(28px) saturate(1.6);\r\n      box-shadow: 0 1px 0 rgba(255,255,255,0.9), 0 4px 24px rgba(0,0,0,0.08), inset 0 -1px 0 rgba(0,0,0,0.06);\r\n    }\r\n\r\n    .nav-wrap {\r\n      max-width: 1180px;\r\n      margin: 0 auto;\r\n      min-height: 74px;\r\n      padding: 0 1.5rem;\r\n      display: flex;\r\n      align-items: center;\r\n      justify-content: space-between;\r\n      gap: 1rem;\r\n    }\r\n\r\n    .brand {\r\n      display: flex;\r\n      align-items: center;\r\n      gap: 0.75rem;\r\n      min-width: 215px;\r\n    }\r\n\r\n    .brand-mark {\r\n      width: 42px;\r\n      height: 42px;\r\n      border-radius: 8px;\r\n      background: linear-gradient(145deg, #4a5158 0%, #1a1d20 100%);\r\n      color: #fff;\r\n      display: grid;\r\n      place-items: center;\r\n      font-weight: 800;\r\n      box-shadow: 0 2px 10px rgba(0,0,0,0.35), inset 0 1px 0 rgba(255,255,255,0.32), inset 0 -1px 0 rgba(0,0,0,0.2);\r\n    }\r\n\r\n    .brand-copy strong {\r\n      display: block;\r\n      font-size: 1rem;\r\n      line-height: 1.1;\r\n      text-transform: uppercase;\r\n    }\r\n\r\n    .brand-copy span {\r\n      color: var(--muted);\r\n      display: block;\r\n      font-size: 0.7rem;\r\n      text-transform: uppercase;\r\n      letter-spacing: 0.08em;\r\n      margin-top: 0.15rem;\r\n    }\r\n\r\n    .nav-links {\r\n      display: flex;\r\n      align-items: center;\r\n      justify-content: center;\r\n      gap: 1.25rem;\r\n      font-size: 0.9rem;\r\n      font-weight: 650;\r\n      color: #475467;\r\n      flex: 1;\r\n    }\r\n\r\n    .nav-links a:hover { color: var(--ink); }\r\n\r\n    .header-actions {\r\n      display: flex;\r\n      align-items: center;\r\n      justify-content: flex-end;\r\n      gap: 0.8rem;\r\n      min-width: 215px;\r\n    }\r\n\r\n    .phone {\r\n      color: #475467;\r\n      font-size: 0.9rem;\r\n      font-weight: 700;\r\n      white-space: nowrap;\r\n    }\r\n\r\n    \/* \u2500\u2500 Buttons \u2500\u2500 *\/\r\n    .btn {\r\n      min-height: 42px;\r\n      border-radius: 8px;\r\n      padding: 0.72rem 1.1rem;\r\n      display: inline-flex;\r\n      align-items: center;\r\n      justify-content: center;\r\n      gap: 0.5rem;\r\n      font-weight: 750;\r\n      transition: transform 160ms ease, box-shadow 160ms ease, background 160ms ease;\r\n      white-space: nowrap;\r\n      position: relative;\r\n      overflow: hidden;\r\n    }\r\n\r\n    .btn:hover { transform: translateY(-1px); }\r\n\r\n    .btn-primary {\r\n      background: linear-gradient(160deg, #3b4145 0%, #1a1d20 100%);\r\n      color: #fff;\r\n      box-shadow: 0 4px 14px rgba(0,0,0,0.35), inset 0 1px 0 rgba(255,255,255,0.15);\r\n    }\r\n    .btn-primary:hover {\r\n      box-shadow: 0 8px 22px rgba(0,0,0,0.4), inset 0 1px 0 rgba(255,255,255,0.2);\r\n    }\r\n    .btn-primary::after {\r\n      content: \"\";\r\n      position: absolute;\r\n      inset: 0;\r\n      background: linear-gradient(180deg, rgba(255,255,255,0.24) 0%, rgba(255,255,255,0.06) 50%, transparent 100%);\r\n      pointer-events: none;\r\n    }\r\n\r\n    .btn-secondary {\r\n      background: rgba(255,255,255,0.88);\r\n      color: var(--ink);\r\n      border: 1px solid rgba(255,255,255,0.75);\r\n      backdrop-filter: blur(8px);\r\n      -webkit-backdrop-filter: blur(8px);\r\n      box-shadow: 0 1px 4px rgba(0,0,0,0.07), inset 0 1px 0 rgba(255,255,255,1), inset 0 -1px 0 rgba(0,0,0,0.04);\r\n    }\r\n    .btn-secondary:hover {\r\n      border-color: rgba(255,255,255,0.9);\r\n      box-shadow: 0 4px 14px rgba(0,0,0,0.1), inset 0 1px 0 #fff;\r\n    }\r\n\r\n    .btn-gold {\r\n      background: linear-gradient(150deg, #d4b06a 0%, #b8903e 100%);\r\n      color: #1a1200;\r\n      box-shadow: 0 4px 16px rgba(199,161,90,0.45), inset 0 1px 0 rgba(255,255,255,0.35);\r\n    }\r\n    .btn-gold:hover {\r\n      box-shadow: 0 8px 24px rgba(199,161,90,0.55), inset 0 1px 0 rgba(255,255,255,0.4);\r\n    }\r\n    .btn-gold::after {\r\n      content: \"\";\r\n      position: absolute;\r\n      inset: 0;\r\n      background: linear-gradient(180deg, rgba(255,255,255,0.42) 0%, rgba(255,255,255,0.08) 50%, transparent 100%);\r\n      pointer-events: none;\r\n    }\r\n\r\n    .btn-ghost {\r\n      background: rgba(255,255,255,0.09);\r\n      color: #fff;\r\n      border: 1px solid rgba(255,255,255,0.18);\r\n      box-shadow: inset 0 1px 0 rgba(255,255,255,0.14);\r\n    }\r\n    .btn-ghost:hover {\r\n      background: rgba(255,255,255,0.14);\r\n      box-shadow: 0 4px 12px rgba(0,0,0,0.2), inset 0 1px 0 rgba(255,255,255,0.2);\r\n    }\r\n\r\n    \/* \u2500\u2500 Hero \u2500\u2500 *\/\r\n    .hero {\r\n      background:\r\n        radial-gradient(ellipse 52% 58% at 88% 18%, rgba(192,212,238,0.68) 0%, transparent 62%),\r\n        radial-gradient(ellipse 42% 52% at 10% 80%, rgba(210,224,244,0.52) 0%, transparent 58%),\r\n        radial-gradient(ellipse 58% 38% at 48% 112%, rgba(200,218,240,0.42) 0%, transparent 55%),\r\n        radial-gradient(ellipse 28% 32% at 62% 72%, rgba(218,230,248,0.36) 0%, transparent 50%),\r\n        linear-gradient(160deg, #eef2f6 0%, #f8f9fb 60%, #e8ecf0 100%);\r\n      border-bottom: 1px solid var(--line);\r\n      position: relative;\r\n      overflow: hidden;\r\n    }\r\n\r\n    \/* Liquid glass orbs \u2014 blurred depth layer *\/\r\n    .hero::after {\r\n      content: \"\";\r\n      position: absolute;\r\n      inset: 0;\r\n      background:\r\n        radial-gradient(ellipse 28% 24% at 78% 14%, rgba(255,255,255,0.72) 0%, transparent 52%),\r\n        radial-gradient(ellipse 22% 32% at 16% 62%, rgba(225,235,252,0.48) 0%, transparent 50%),\r\n        radial-gradient(ellipse 18% 22% at 52% 88%, rgba(215,228,248,0.38) 0%, transparent 48%);\r\n      filter: blur(24px);\r\n      pointer-events: none;\r\n      z-index: 0;\r\n    }\r\n\r\n    \/* Glossy highlight sweep across hero *\/\r\n    .hero::before {\r\n      content: \"\";\r\n      position: absolute;\r\n      top: -60%;\r\n      left: -20%;\r\n      width: 70%;\r\n      height: 160%;\r\n      background: linear-gradient(135deg, rgba(255,255,255,0.82) 0%, rgba(255,255,255,0.22) 40%, transparent 65%);\r\n      pointer-events: none;\r\n      transform: rotate(-12deg);\r\n      z-index: 1;\r\n    }\r\n\r\n    .hero-inner {\r\n      max-width: 1180px;\r\n      margin: 0 auto;\r\n      padding: clamp(2.5rem, 4vw, 3rem) 1.5rem;\r\n      display: grid;\r\n      grid-template-columns: minmax(0, 1fr) minmax(340px, 0.92fr);\r\n      gap: clamp(2.5rem, 5vw, 4.5rem);\r\n      align-items: center;\r\n      position: relative;\r\n    }\r\n\r\n    .eyebrow {\r\n      display: inline-flex;\r\n      align-items: center;\r\n      gap: 0.45rem;\r\n      padding: 0.4rem 0.75rem;\r\n      border-radius: 999px;\r\n      background: #fff;\r\n      border: 1px solid var(--line);\r\n      color: #475467;\r\n      font-size: 0.78rem;\r\n      font-weight: 750;\r\n      margin-bottom: 1.25rem;\r\n      background: rgba(255,255,255,0.88);\r\n      backdrop-filter: blur(12px);\r\n      -webkit-backdrop-filter: blur(12px);\r\n      box-shadow: 0 1px 4px rgba(0,0,0,0.07), inset 0 1px 0 rgba(255,255,255,1), 0 0 0 1px rgba(255,255,255,0.55);\r\n    }\r\n\r\n    .pulse {\r\n      width: 8px;\r\n      height: 8px;\r\n      border-radius: 50%;\r\n      background: var(--green);\r\n      box-shadow: 0 0 0 4px rgba(36,121,90,0.18);\r\n    }\r\n\r\n    h1, h2, h3 {\r\n      margin: 0;\r\n      line-height: 1.04;\r\n      letter-spacing: -0.01em;\r\n    }\r\n\r\n    h1 {\r\n      font-size: clamp(2.55rem, 6vw, 5rem);\r\n      max-width: 680px;\r\n    }\r\n\r\n    h1 span { color: #6c757d; font-weight: 520; }\r\n\r\n    .hero-copy {\r\n      color: var(--muted);\r\n      font-size: 1.06rem;\r\n      line-height: 1.7;\r\n      max-width: 640px;\r\n      margin: 1.5rem 0;\r\n    }\r\n\r\n    .proof-grid {\r\n      display: grid;\r\n      grid-template-columns: repeat(2, minmax(0, 1fr));\r\n      gap: 0.75rem 1.25rem;\r\n      margin: 0 0 1.5rem;\r\n    }\r\n\r\n    .proof-item {\r\n      display: flex;\r\n      align-items: center;\r\n      gap: 0.6rem;\r\n      color: #344054;\r\n      font-size: 0.92rem;\r\n      font-weight: 700;\r\n    }\r\n\r\n    .icon {\r\n      width: 1.2rem;\r\n      height: 1.2rem;\r\n      flex: 0 0 auto;\r\n      display: inline-grid;\r\n      place-items: center;\r\n      border-radius: 50%;\r\n      background: linear-gradient(145deg, #f2f5f9, #cdd4de);\r\n      color: var(--steel);\r\n      font-size: 0.72rem;\r\n      font-weight: 900;\r\n      box-shadow: 0 1px 3px rgba(0,0,0,0.14), inset 0 1px 0 rgba(255,255,255,0.95), inset 0 -1px 0 rgba(0,0,0,0.06);\r\n    }\r\n\r\n    .hero-actions {\r\n      display: flex;\r\n      flex-wrap: wrap;\r\n      gap: 0.85rem;\r\n    }\r\n\r\n    \/* \u2500\u2500 Preview Card \u2500\u2500 *\/\r\n    .preview-card {\r\n      position: relative;\r\n      overflow: hidden;\r\n      min-height: 440px;\r\n      border-radius: 12px;\r\n      border: 8px solid rgba(255,255,255,0.96);\r\n      box-shadow: 0 32px 80px rgba(16,24,40,0.28), 0 0 0 1px rgba(255,255,255,0.5), inset 0 2px 0 rgba(255,255,255,0.95);\r\n      background: #23272b;\r\n    }\r\n\r\n    \/* Gloss sheen over the card *\/\r\n    .preview-card::after {\r\n      content: \"\";\r\n      position: absolute;\r\n      top: 0; left: 0; right: 0;\r\n      height: 60%;\r\n      background: linear-gradient(160deg, rgba(255,255,255,0.28) 0%, rgba(255,255,255,0.08) 40%, transparent 100%);\r\n      pointer-events: none;\r\n      z-index: 2;\r\n    }\r\n\r\n    .garage-art {\r\n      width: 100%;\r\n      height: 100%;\r\n      min-height: 440px;\r\n      display: block;\r\n    }\r\n\r\n    .preview-label {\r\n      position: absolute;\r\n      left: 1rem;\r\n      right: 1rem;\r\n      bottom: 1rem;\r\n      display: flex;\r\n      justify-content: space-between;\r\n      align-items: center;\r\n      gap: 1rem;\r\n      padding: 0.95rem 1.1rem;\r\n      border-radius: 10px;\r\n      background: rgba(8,10,13,0.92);\r\n      backdrop-filter: blur(20px) saturate(1.5);\r\n      -webkit-backdrop-filter: blur(20px) saturate(1.5);\r\n      color: #fff;\r\n      border: 1px solid rgba(255,255,255,0.16);\r\n      box-shadow: 0 8px 32px rgba(0,0,0,0.4), inset 0 1px 0 rgba(255,255,255,0.2), inset 0 -1px 0 rgba(255,255,255,0.06);\r\n      z-index: 3;\r\n    }\r\n\r\n    .preview-label strong { display: block; }\r\n    .preview-label span { display: block; color: #cfd4dc; font-size: 0.82rem; margin-top: 0.2rem; }\r\n\r\n    .tag {\r\n      background: linear-gradient(135deg, var(--gold-light) 0%, var(--gold) 100%);\r\n      color: #1a1000;\r\n      padding: 0.35rem 0.6rem;\r\n      border-radius: 999px;\r\n      font-size: 0.72rem;\r\n      font-weight: 900;\r\n      box-shadow: 0 2px 8px rgba(199,161,90,0.4), inset 0 1px 0 rgba(255,255,255,0.35);\r\n    }\r\n\r\n    \/* \u2500\u2500 Trust Strip \u2500\u2500 *\/\r\n    .trust-strip {\r\n      background: linear-gradient(90deg, #1a1d20 0%, #2a2d30 50%, #1a1d20 100%);\r\n      color: rgba(255,255,255,0.72);\r\n      padding: 1.6rem 1.5rem;\r\n      text-align: center;\r\n      border-bottom: 1px solid rgba(255,255,255,0.06);\r\n    }\r\n\r\n    .trust-strip p {\r\n      margin: 0 0 0.85rem;\r\n      color: rgba(255,255,255,0.4);\r\n      text-transform: uppercase;\r\n      font-size: 0.74rem;\r\n      font-weight: 800;\r\n      letter-spacing: 0.1em;\r\n    }\r\n\r\n    .trust-list {\r\n      max-width: 1020px;\r\n      margin: 0 auto;\r\n      display: flex;\r\n      justify-content: center;\r\n      gap: 1rem 2.5rem;\r\n      flex-wrap: wrap;\r\n      font-weight: 850;\r\n      font-size: 0.88rem;\r\n    }\r\n\r\n    \/* \u2500\u2500 Sections \u2500\u2500 *\/\r\n    section {\r\n      padding: clamp(3rem, 3.5vw, 2.75rem) 1.5rem;\r\n    }\r\n\r\n    \/* Break up adjacent white sections so the shared gap doesn't look oversized *\/\r\n    #process {\r\n      border-bottom: 1px solid var(--line);\r\n    }\r\n\r\n    .section-inner {\r\n      max-width: 1180px;\r\n      margin: 0 auto;\r\n    }\r\n\r\n    .section-head {\r\n      max-width: 720px;\r\n      margin: 0 auto 2.75rem;\r\n      text-align: center;\r\n    }\r\n\r\n    .section-head h2 {\r\n      font-size: clamp(2rem, 4vw, 3rem);\r\n      letter-spacing: -0.02em;\r\n    }\r\n\r\n    .section-head p {\r\n      color: var(--muted);\r\n      line-height: 1.65;\r\n      margin: 1rem 0 0;\r\n      font-size: 1.02rem;\r\n    }\r\n\r\n    \/* \u2500\u2500 Service Grid \u2500\u2500 *\/\r\n    .service-grid {\r\n      display: grid;\r\n      grid-template-columns: repeat(4, minmax(0, 1fr));\r\n      gap: 1.1rem;\r\n    }\r\n\r\n    \/* \u2500\u2500 Pricing Grid \u2500\u2500 *\/\r\n    .pricing-grid {\r\n      display: grid;\r\n      grid-template-columns: repeat(3, minmax(0, 1fr));\r\n      gap: 1.1rem;\r\n    }\r\n\r\n    \/* \u2500\u2500 Cards \u2500\u2500 *\/\r\n    .service-card, .price-card {\r\n      border: 1px solid rgba(255,255,255,0.82);\r\n      border-radius: 10px;\r\n      padding: 1.5rem;\r\n      background: linear-gradient(160deg, rgba(255,255,255,0.98) 0%, rgba(244,247,251,0.94) 100%);\r\n      min-height: 100%;\r\n      box-shadow: 0 1px 3px rgba(0,0,0,0.06), 0 4px 24px rgba(0,0,0,0.07),\r\n                  inset 0 1px 0 rgba(255,255,255,1),\r\n                  inset 1px 0 0 rgba(255,255,255,0.6),\r\n                  inset -1px 0 0 rgba(255,255,255,0.4);\r\n      backdrop-filter: blur(4px);\r\n      -webkit-backdrop-filter: blur(4px);\r\n      transition: transform 200ms ease, box-shadow 200ms ease;\r\n      position: relative;\r\n      overflow: hidden;\r\n    }\r\n\r\n    .service-card::before, .price-card::before {\r\n      content: \"\";\r\n      position: absolute;\r\n      top: 0; left: 0; right: 0;\r\n      height: 2px;\r\n      background: linear-gradient(90deg, transparent 0%, rgba(255,255,255,0.6) 25%, rgba(255,255,255,1) 50%, rgba(255,255,255,0.6) 75%, transparent 100%);\r\n    }\r\n\r\n    \/* Diagonal glass streak *\/\r\n    .service-card::after, .price-card::after {\r\n      content: \"\";\r\n      position: absolute;\r\n      top: 0; left: -30%;\r\n      width: 60%;\r\n      height: 100%;\r\n      background: linear-gradient(108deg, transparent 35%, rgba(255,255,255,0.16) 50%, transparent 65%);\r\n      pointer-events: none;\r\n    }\r\n\r\n    .service-card:hover, .price-card:hover {\r\n      transform: translateY(-2px);\r\n      box-shadow: 0 4px 8px rgba(0,0,0,0.08), 0 16px 40px rgba(0,0,0,0.1),\r\n                  inset 0 1px 0 rgba(255,255,255,1),\r\n                  inset 1px 0 0 rgba(255,255,255,0.7);\r\n    }\r\n\r\n    .service-card h3, .price-card h3 {\r\n      font-size: 1.15rem;\r\n      margin-bottom: 0.65rem;\r\n      letter-spacing: -0.01em;\r\n    }\r\n\r\n    .service-card p, .price-card p {\r\n      color: var(--muted);\r\n      line-height: 1.65;\r\n      font-size: 0.93rem;\r\n      margin: 0;\r\n    }\r\n\r\n    .meta-row {\r\n      border-top: 1px solid var(--line);\r\n      display: flex;\r\n      justify-content: space-between;\r\n      align-items: center;\r\n      gap: 1rem;\r\n      color: #667085;\r\n      font-size: 0.78rem;\r\n      font-weight: 850;\r\n      text-transform: uppercase;\r\n      margin-top: 1.35rem;\r\n      padding-top: 1.1rem;\r\n      letter-spacing: 0.04em;\r\n    }\r\n\r\n    .meta-row strong { color: var(--ink); }\r\n\r\n    \/* \u2500\u2500 Visualizer Section \u2500\u2500 *\/\r\n    .visualizer-section {\r\n      background: linear-gradient(160deg, #191c1f 0%, #202326 60%, #17191b 100%);\r\n      color: #fff;\r\n      border-top: 1px solid rgba(255,255,255,0.07);\r\n      border-bottom: 1px solid rgba(255,255,255,0.07);\r\n      position: relative;\r\n      overflow: hidden;\r\n    }\r\n\r\n    .visualizer-section::before {\r\n      content: \"\";\r\n      position: absolute;\r\n      top: 0; left: 0; right: 0;\r\n      height: 1px;\r\n      background: linear-gradient(90deg, transparent, rgba(255,255,255,0.18), transparent);\r\n    }\r\n\r\n    .visualizer-section .section-head p { color: #b7c0ca; }\r\n\r\n    \/* \u2500\u2500 Studio layout \u2500\u2500 *\/\r\n    .studio {\r\n      display: grid;\r\n      grid-template-columns: 360px minmax(0, 1fr);\r\n      gap: 1.1rem;\r\n      align-items: start;\r\n    }\r\n\r\n    \/* \u2500\u2500 Panel \u2500\u2500 *\/\r\n    .panel {\r\n      border: 1px solid rgba(255,255,255,0.16);\r\n      border-radius: 10px;\r\n      background: linear-gradient(160deg, rgba(255,255,255,0.11) 0%, rgba(255,255,255,0.04) 100%);\r\n      padding: 1.1rem;\r\n      box-shadow: 0 8px 32px rgba(0,0,0,0.28), inset 0 1px 0 rgba(255,255,255,0.22), inset 1px 0 0 rgba(255,255,255,0.1), 0 0 0 1px rgba(255,255,255,0.04);\r\n      backdrop-filter: blur(16px) saturate(1.4);\r\n      -webkit-backdrop-filter: blur(16px) saturate(1.4);\r\n    }\r\n\r\n    .control-group + .control-group { margin-top: 1.35rem; }\r\n\r\n    .control-label {\r\n      display: flex;\r\n      justify-content: space-between;\r\n      align-items: center;\r\n      gap: 1rem;\r\n      color: #cbd3dc;\r\n      font-size: 0.74rem;\r\n      font-weight: 850;\r\n      text-transform: uppercase;\r\n      letter-spacing: 0.07em;\r\n      margin-bottom: 0.75rem;\r\n    }\r\n\r\n    \/* \u2500\u2500 Upload box \u2500\u2500 *\/\r\n    .upload-box {\r\n      position: relative;\r\n      min-height: 104px;\r\n      border: 2px dashed rgba(255,255,255,0.2);\r\n      border-radius: 9px;\r\n      background: rgba(0,0,0,0.22);\r\n      display: grid;\r\n      place-items: center;\r\n      text-align: center;\r\n      padding: 1.1rem;\r\n      transition: border-color 180ms;\r\n    }\r\n\r\n    .upload-box:hover { border-color: rgba(255,255,255,0.5); }\r\n\r\n    .upload-box input {\r\n      position: absolute;\r\n      inset: 0;\r\n      opacity: 0;\r\n      cursor: pointer;\r\n    }\r\n\r\n    .upload-box strong { display: block; font-size: 0.9rem; }\r\n    .upload-box span { color: #a9b3be; font-size: 0.78rem; display: block; margin-top: 0.25rem; overflow-wrap: anywhere; }\r\n\r\n    \/* \u2500\u2500 Segmented control \u2500\u2500 *\/\r\n    .segmented {\r\n      display: grid;\r\n      grid-template-columns: repeat(3, 1fr);\r\n      gap: 0.3rem;\r\n      padding: 0.22rem;\r\n      border-radius: 9px;\r\n      background: rgba(0,0,0,0.3);\r\n      margin-bottom: 0.85rem;\r\n      border: 1px solid rgba(255,255,255,0.08);\r\n      box-shadow: inset 0 2px 6px rgba(0,0,0,0.25);\r\n    }\r\n\r\n    .segment {\r\n      min-height: 36px;\r\n      border-radius: 6px;\r\n      background: transparent;\r\n      color: #c8d0d9;\r\n      font-size: 0.82rem;\r\n      font-weight: 800;\r\n      transition: background 160ms, color 160ms, box-shadow 160ms;\r\n    }\r\n\r\n    .segment.active {\r\n      background: linear-gradient(160deg, #fff 0%, #e8ecf0 100%);\r\n      color: var(--ink);\r\n      box-shadow: 0 2px 8px rgba(0,0,0,0.2), inset 0 1px 0 rgba(255,255,255,0.9);\r\n    }\r\n\r\n    \/* \u2500\u2500 Finish list \u2500\u2500 *\/\r\n    .finish-list { display: grid; gap: 0.5rem; }\r\n\r\n    .finish-button {\r\n      min-height: 64px;\r\n      width: 100%;\r\n      border-radius: 9px;\r\n      border: 1px solid rgba(255,255,255,0.14);\r\n      background: linear-gradient(160deg, rgba(255,255,255,0.1) 0%, rgba(255,255,255,0.04) 100%);\r\n      color: #fff;\r\n      display: grid;\r\n      grid-template-columns: 38px minmax(0, 1fr) auto;\r\n      align-items: center;\r\n      gap: 0.75rem;\r\n      padding: 0.65rem 0.75rem;\r\n      text-align: left;\r\n      transition: background 160ms, border-color 160ms, box-shadow 160ms;\r\n      box-shadow: inset 0 1px 0 rgba(255,255,255,0.14), inset 0 -1px 0 rgba(0,0,0,0.12);\r\n    }\r\n\r\n    .finish-button:hover {\r\n      background: linear-gradient(160deg, rgba(255,255,255,0.18) 0%, rgba(255,255,255,0.08) 100%);\r\n      border-color: rgba(255,255,255,0.32);\r\n      box-shadow: 0 4px 16px rgba(0,0,0,0.22), inset 0 1px 0 rgba(255,255,255,0.22), inset 0 -1px 0 rgba(0,0,0,0.1);\r\n    }\r\n\r\n    .finish-button.active {\r\n      background: linear-gradient(160deg, rgba(255,255,255,0.2) 0%, rgba(255,255,255,0.09) 100%);\r\n      border-color: rgba(255,255,255,0.42);\r\n      box-shadow: 0 4px 18px rgba(0,0,0,0.24), inset 0 1px 0 rgba(255,255,255,0.28), inset 0 -1px 0 rgba(0,0,0,0.1);\r\n    }\r\n\r\n    \/* \u2500\u2500 Swatches \u2500\u2500 *\/\r\n    .swatch {\r\n      width: 36px;\r\n      height: 36px;\r\n      border-radius: 8px;\r\n      border: 1px solid rgba(255,255,255,0.28);\r\n      overflow: hidden;\r\n      background: var(--swatch);\r\n      box-shadow: 0 2px 8px rgba(0,0,0,0.25), inset 0 1px 0 rgba(255,255,255,0.4);\r\n      position: relative;\r\n    }\r\n\r\n    .swatch::after {\r\n      content: \"\";\r\n      position: absolute;\r\n      top: 0; left: 0; right: 0;\r\n      height: 50%;\r\n      background: linear-gradient(180deg, rgba(255,255,255,0.72) 0%, rgba(255,255,255,0.18) 60%, transparent 100%);\r\n      border-radius: 7px 7px 0 0;\r\n    }\r\n\r\n    .swatch.flake {\r\n      background:\r\n        radial-gradient(circle at 20% 25%, rgba(255,255,255,.86) 0 2px, transparent 3px),\r\n        radial-gradient(circle at 70% 35%, rgba(20,20,20,.7) 0 2px, transparent 3px),\r\n        radial-gradient(circle at 42% 72%, rgba(199,161,90,.85) 0 2px, transparent 3px),\r\n        var(--swatch);\r\n    }\r\n\r\n    .swatch.metallic {\r\n      background:\r\n        linear-gradient(135deg, rgba(255,255,255,.65), transparent 28%, rgba(0,0,0,.18) 55%, rgba(255,255,255,.35)),\r\n        var(--swatch);\r\n    }\r\n\r\n    .finish-title { display: block; font-size: 0.9rem; font-weight: 850; overflow-wrap: anywhere; }\r\n    .finish-type { display: block; color: #a9b3be; font-size: 0.74rem; margin-top: 0.18rem; }\r\n    .select-mark { color: var(--gold); font-size: 1.1rem; font-weight: 900; }\r\n\r\n    input[type=\"range\"] { width: 100%; accent-color: var(--gold); }\r\n\r\n    \/* \u2500\u2500 Canvas shell \u2500\u2500 *\/\r\n    .canvas-shell {\r\n      overflow: hidden;\r\n      border-radius: 10px;\r\n      border: 1px solid rgba(255,255,255,0.18);\r\n      background: #0d0f11;\r\n      box-shadow: 0 24px 72px rgba(0,0,0,0.4), inset 0 1px 0 rgba(255,255,255,0.22), inset 0 0 0 1px rgba(255,255,255,0.06);\r\n    }\r\n\r\n    .canvas-toolbar {\r\n      min-height: 44px;\r\n      padding: 0.65rem 1rem;\r\n      display: flex;\r\n      align-items: center;\r\n      justify-content: space-between;\r\n      gap: 0.75rem;\r\n      background: linear-gradient(180deg, rgba(255,255,255,0.07) 0%, rgba(0,0,0,0.18) 100%);\r\n      border-bottom: 1px solid rgba(255,255,255,0.08);\r\n      color: #c5ced8;\r\n      font-size: 0.82rem;\r\n    }\r\n\r\n    .canvas-toolbar span { overflow-wrap: anywhere; flex: 1; }\r\n\r\n    .zoom-controls {\r\n      display: flex;\r\n      align-items: center;\r\n      gap: 0.3rem;\r\n      flex-shrink: 0;\r\n    }\r\n\r\n    .zoom-btn {\r\n      min-height: 26px;\r\n      min-width: 26px;\r\n      border-radius: 5px;\r\n      background: rgba(255,255,255,0.1);\r\n      color: #c5ced8;\r\n      border: 1px solid rgba(255,255,255,0.15);\r\n      font-size: 1rem;\r\n      line-height: 1;\r\n      display: grid;\r\n      place-items: center;\r\n      padding: 0 0.3rem;\r\n      transition: background 140ms;\r\n    }\r\n\r\n    .zoom-btn:hover { background: rgba(255,255,255,0.22); }\r\n\r\n    #zoom-level {\r\n      font-size: 0.76rem;\r\n      font-weight: 800;\r\n      color: #c5ced8;\r\n      min-width: 2.8rem;\r\n      text-align: center;\r\n    }\r\n\r\n    .canvas-wrap { padding: 0.85rem; display: grid; place-items: center; }\r\n\r\n    canvas {\r\n      width: 100%;\r\n      height: auto;\r\n      max-height: 620px;\r\n      background: #2c3135;\r\n      border-radius: 6px;\r\n      cursor: crosshair;\r\n      touch-action: none;\r\n      box-shadow: 0 4px 24px rgba(0,0,0,0.3);\r\n    }\r\n\r\n    canvas.pan-mode { cursor: grab; }\r\n    canvas.is-panning { cursor: grabbing; }\r\n\r\n    .small-actions {\r\n      display: grid;\r\n      grid-template-columns: 1fr 1fr;\r\n      gap: 0.5rem;\r\n      margin-top: 0.9rem;\r\n    }\r\n\r\n    .small-actions .btn { min-height: 38px; font-size: 0.82rem; padding: 0.6rem; }\r\n\r\n    .mode-grid {\r\n      display: grid;\r\n      grid-template-columns: repeat(2, minmax(0, 1fr));\r\n      gap: 0.45rem;\r\n    }\r\n\r\n    .mode-button {\r\n      min-height: 40px;\r\n      border-radius: 8px;\r\n      border: 1px solid rgba(255,255,255,0.13);\r\n      background: rgba(255,255,255,0.055);\r\n      color: #d8dee6;\r\n      font-size: 0.82rem;\r\n      font-weight: 800;\r\n      transition: background 160ms, box-shadow 160ms;\r\n    }\r\n\r\n    .mode-button.active {\r\n      background: linear-gradient(160deg, #fff 0%, #e8ecf0 100%);\r\n      border-color: #fff;\r\n      color: var(--ink);\r\n      box-shadow: 0 2px 10px rgba(0,0,0,0.2), inset 0 1px 0 rgba(255,255,255,0.9);\r\n    }\r\n\r\n    .range-stack { display: grid; gap: 0.75rem; }\r\n\r\n    \/* \u2500\u2500 Steps \u2500\u2500 *\/\r\n    .steps {\r\n      display: grid;\r\n      grid-template-columns: repeat(4, minmax(0, 1fr));\r\n      gap: 1.25rem;\r\n    }\r\n\r\n    .step { border-top: 2px solid var(--line); padding-top: 1.1rem; }\r\n    .step-num { color: #98a2b3; font-weight: 900; margin-bottom: 0.5rem; }\r\n    .step h3 { font-size: 1.1rem; margin-bottom: 0.5rem; letter-spacing: -0.01em; }\r\n    .step p { color: var(--muted); line-height: 1.6; margin: 0; font-size: 0.92rem; }\r\n\r\n    \/* \u2500\u2500 Price cards \u2500\u2500 *\/\r\n    .price-card.featured {\r\n      border: 2px solid var(--charcoal);\r\n      position: relative;\r\n      box-shadow: 0 0 0 5px rgba(26,29,32,0.07), 0 8px 28px rgba(0,0,0,0.12), inset 0 1px 0 rgba(255,255,255,0.95);\r\n    }\r\n\r\n    .price {\r\n      font-size: 2.4rem;\r\n      font-weight: 900;\r\n      margin: 0.85rem 0 0.3rem;\r\n      letter-spacing: -0.03em;\r\n      background: linear-gradient(135deg, #1a1d20 30%, #52616b 100%);\r\n      -webkit-background-clip: text;\r\n      -webkit-text-fill-color: transparent;\r\n      background-clip: text;\r\n    }\r\n\r\n    .price small {\r\n      font-size: 0.9rem;\r\n      color: var(--muted);\r\n      font-weight: 700;\r\n      -webkit-text-fill-color: var(--muted);\r\n    }\r\n\r\n    .feature-list {\r\n      padding: 0;\r\n      margin: 1.2rem 0 0;\r\n      list-style: none;\r\n      display: grid;\r\n      gap: 0.65rem;\r\n      color: #475467;\r\n      font-size: 0.92rem;\r\n    }\r\n\r\n    .feature-list li { display: flex; gap: 0.55rem; align-items: flex-start; }\r\n\r\n    \/* \u2500\u2500 Quote section \u2500\u2500 *\/\r\n    .quote-section {\r\n      background: linear-gradient(160deg, #1a1d20 0%, #2a2d30 50%, #1a1d20 100%);\r\n      color: #fff;\r\n      position: relative;\r\n    }\r\n\r\n    .quote-section::before {\r\n      content: \"\";\r\n      position: absolute;\r\n      top: 0; left: 0; right: 0;\r\n      height: 1px;\r\n      background: linear-gradient(90deg, transparent, rgba(255,255,255,0.2), transparent);\r\n    }\r\n\r\n    .quote-section .section-head p { color: #bac3ce; }\r\n\r\n    \/* \u2500\u2500 Quote form \u2500\u2500 *\/\r\n    .quote-form {\r\n      max-width: 760px;\r\n      margin: 0 auto;\r\n      display: grid;\r\n      grid-template-columns: repeat(2, minmax(0, 1fr));\r\n      gap: 0.85rem;\r\n      padding: 1.35rem;\r\n      border: 1px solid rgba(255,255,255,0.13);\r\n      border-radius: 12px;\r\n      background: linear-gradient(160deg, rgba(255,255,255,0.07) 0%, rgba(255,255,255,0.03) 100%);\r\n      box-shadow: 0 16px 48px rgba(0,0,0,0.28), inset 0 1px 0 rgba(255,255,255,0.1);\r\n    }\r\n\r\n    .field { display: grid; gap: 0.4rem; }\r\n\r\n    .field label {\r\n      color: #c9d1da;\r\n      font-size: 0.74rem;\r\n      font-weight: 850;\r\n      text-transform: uppercase;\r\n      letter-spacing: 0.07em;\r\n    }\r\n\r\n    .field input, .field select {\r\n      width: 100%;\r\n      min-height: 46px;\r\n      border-radius: 8px;\r\n      border: 1px solid rgba(255,255,255,0.14);\r\n      background: rgba(0,0,0,0.22);\r\n      color: #fff;\r\n      padding: 0 0.9rem;\r\n      outline: none;\r\n      transition: border-color 160ms, box-shadow 160ms;\r\n    }\r\n\r\n    .field input:focus, .field select:focus {\r\n      border-color: rgba(255,255,255,0.5);\r\n      box-shadow: 0 0 0 3px rgba(255,255,255,0.1);\r\n    }\r\n\r\n    .quote-form button { grid-column: 1 \/ -1; margin-top: 0.5rem; }\r\n\r\n    \/* \u2500\u2500 Forminator form \u2014 match quote-form card \u2500\u2500 *\/\r\n    .quote-section .forminator-ui {\r\n      max-width: 760px !important;\r\n      margin: 0 auto !important;\r\n      background: transparent !important;\r\n      border: none !important;\r\n      box-shadow: none !important;\r\n      padding: 0 !important;\r\n      display: block !important;\r\n    }\r\n\r\n    .quote-section .forminator-form {\r\n      padding: 1.35rem !important;\r\n      border: 1px solid rgba(255,255,255,0.13) !important;\r\n      border-radius: 12px !important;\r\n      background: linear-gradient(160deg, rgba(255,255,255,0.07) 0%, rgba(255,255,255,0.03) 100%) !important;\r\n      box-shadow: 0 16px 48px rgba(0,0,0,0.28), inset 0 1px 0 rgba(255,255,255,0.1) !important;\r\n    }\r\n\r\n    .quote-section .forminator-row {\r\n      margin-bottom: 0 !important;\r\n    }\r\n\r\n    .quote-section .forminator-col,\r\n    .quote-section [class*=\"forminator-col-\"] {\r\n      padding: 0.425rem !important;\r\n    }\r\n\r\n    .quote-section .forminator-row:first-child [class*=\"forminator-col-\"],\r\n    .quote-section .forminator-row:first-of-type [class*=\"forminator-col-\"] {\r\n      padding-top: 0 !important;\r\n    }\r\n\r\n    .quote-section .forminator-field {\r\n      margin-bottom: 0 !important;\r\n    }\r\n\r\n    \/* Labels *\/\r\n    .quote-section .forminator-label,\r\n    .quote-section .forminator-field > label {\r\n      color: #c9d1da !important;\r\n      font-size: 0.74rem !important;\r\n      font-weight: 850 !important;\r\n      text-transform: uppercase !important;\r\n      letter-spacing: 0.07em !important;\r\n      margin-bottom: 0.4rem !important;\r\n      display: block !important;\r\n    }\r\n\r\n    .quote-section .forminator-required { color: var(--gold) !important; }\r\n\r\n    \/* Inputs & selects *\/\r\n    .quote-section .forminator-input,\r\n    .quote-section .forminator-custom-input,\r\n    .quote-section .forminator-field input[type=\"text\"],\r\n    .quote-section .forminator-field input[type=\"email\"],\r\n    .quote-section .forminator-field input[type=\"tel\"],\r\n    .quote-section .forminator-field input[type=\"number\"],\r\n    .quote-section .forminator-field input[type=\"url\"],\r\n    .quote-section .forminator-field select,\r\n    .quote-section .forminator-field textarea {\r\n      width: 100% !important;\r\n      min-height: 46px !important;\r\n      border-radius: 8px !important;\r\n      border: 1px solid rgba(255,255,255,0.14) !important;\r\n      background: rgba(0,0,0,0.22) !important;\r\n      color: #fff !important;\r\n      padding: 0 0.9rem !important;\r\n      outline: none !important;\r\n      box-shadow: none !important;\r\n      font-family: inherit !important;\r\n      font-size: inherit !important;\r\n      transition: border-color 160ms, box-shadow 160ms !important;\r\n      -webkit-appearance: none !important;\r\n      appearance: none !important;\r\n    }\r\n\r\n    .quote-section .forminator-field textarea {\r\n      min-height: 100px !important;\r\n      padding: 0.7rem 0.9rem !important;\r\n      resize: vertical !important;\r\n    }\r\n\r\n    .quote-section .forminator-input:focus,\r\n    .quote-section .forminator-custom-input:focus,\r\n    .quote-section .forminator-field input:focus,\r\n    .quote-section .forminator-field select:focus,\r\n    .quote-section .forminator-field textarea:focus {\r\n      border-color: rgba(255,255,255,0.5) !important;\r\n      box-shadow: 0 0 0 3px rgba(255,255,255,0.1) !important;\r\n    }\r\n\r\n    \/* Placeholder *\/\r\n    .quote-section .forminator-field ::placeholder { color: rgba(255,255,255,0.32) !important; }\r\n    .quote-section .forminator-field ::-webkit-input-placeholder { color: rgba(255,255,255,0.32) !important; }\r\n\r\n    \/* Select dropdown arrow + force white text (browsers ignore color on select without color-scheme) *\/\r\n    .quote-section .forminator-field select {\r\n      background-image: url(\"data:image\/svg+xml,%3Csvg xmlns='http:\/\/www.w3.org\/2000\/svg' width='12' height='8' viewBox='0 0 12 8'%3E%3Cpath fill='%23c9d1da' d='M6 8L0 0h12z'\/%3E%3C\/svg%3E\") !important;\r\n      background-repeat: no-repeat !important;\r\n      background-position: right 0.9rem center !important;\r\n      background-size: 10px 6px !important;\r\n      padding-right: 2.2rem !important;\r\n      color: #fff !important;\r\n      color-scheme: dark !important;\r\n    }\r\n\r\n    \/* Forminator custom-select rendered text (span overlay Forminator uses instead of native select) *\/\r\n    .quote-section .forminator-select .forminator-select--field,\r\n    .quote-section .forminator-custom-select,\r\n    .quote-section .forminator-custom-select span,\r\n    .quote-section .forminator-field .chosen-single span,\r\n    .quote-section .forminator-field .chosen-single,\r\n    .quote-section .forminator-field .chosen-container-single .chosen-single {\r\n      color: #fff !important;\r\n      background: rgba(0,0,0,0.22) !important;\r\n    }\r\n\r\n    .quote-section .forminator-field select option {\r\n      background: #1a1d20;\r\n      color: #fff;\r\n    }\r\n\r\n    \/* Submit button \u2014 matches .btn-gold *\/\r\n    .quote-section .forminator-button,\r\n    .quote-section .forminator-button-submit {\r\n      width: 100% !important;\r\n      min-height: 42px !important;\r\n      border-radius: 8px !important;\r\n      padding: 0.72rem 1.1rem !important;\r\n      display: inline-flex !important;\r\n      align-items: center !important;\r\n      justify-content: center !important;\r\n      gap: 0.5rem !important;\r\n      font-weight: 750 !important;\r\n      font-size: 1rem !important;\r\n      font-family: inherit !important;\r\n      cursor: pointer !important;\r\n      border: 0 !important;\r\n      background: linear-gradient(150deg, #d4b06a 0%, #b8903e 100%) !important;\r\n      color: #1a1200 !important;\r\n      box-shadow: 0 4px 16px rgba(199,161,90,0.45), inset 0 1px 0 rgba(255,255,255,0.35) !important;\r\n      transition: transform 160ms ease, box-shadow 160ms ease !important;\r\n      margin-top: 0.5rem !important;\r\n      white-space: nowrap !important;\r\n      position: relative !important;\r\n      overflow: hidden !important;\r\n    }\r\n\r\n    .quote-section .forminator-button:hover,\r\n    .quote-section .forminator-button-submit:hover {\r\n      transform: translateY(-1px) !important;\r\n      box-shadow: 0 8px 24px rgba(199,161,90,0.55), inset 0 1px 0 rgba(255,255,255,0.4) !important;\r\n    }\r\n\r\n    \/* Gloss sheen on button *\/\r\n    .quote-section .forminator-button::after,\r\n    .quote-section .forminator-button-submit::after {\r\n      content: \"\" !important;\r\n      position: absolute !important;\r\n      inset: 0 !important;\r\n      background: linear-gradient(180deg, rgba(255,255,255,0.2) 0%, transparent 55%) !important;\r\n      pointer-events: none !important;\r\n    }\r\n\r\n    \/* Validation errors *\/\r\n    .quote-section .forminator-field--error .forminator-input,\r\n    .quote-section .forminator-field--error input,\r\n    .quote-section .forminator-field--error select,\r\n    .quote-section .forminator-field--error textarea {\r\n      border-color: rgba(248,113,113,0.6) !important;\r\n    }\r\n\r\n    .quote-section .forminator-error-inline,\r\n    .quote-section .forminator-field .forminator-error-message {\r\n      color: #f87171 !important;\r\n      font-size: 0.74rem !important;\r\n      margin-top: 0.3rem !important;\r\n    }\r\n\r\n    \/* Success \/ response message *\/\r\n    .quote-section .forminator-response-output {\r\n      color: #c9d1da !important;\r\n      text-align: center !important;\r\n      padding: 0.75rem !important;\r\n      border-radius: 8px !important;\r\n    }\r\n\r\n    .quote-section .forminator-response-output.forminator-success {\r\n      background: rgba(36,121,90,0.2) !important;\r\n      border: 1px solid rgba(36,121,90,0.4) !important;\r\n      color: #6ee7b7 !important;\r\n    }\r\n\r\n    \/* \u2500\u2500 Footer \u2500\u2500 *\/\r\n    footer {\r\n      background: #0f1114;\r\n      color: #a3acb7;\r\n      padding: 1.6rem 1.5rem;\r\n      border-top: 1px solid rgba(255,255,255,0.06);\r\n    }\r\n\r\n    .footer-inner {\r\n      max-width: 1180px;\r\n      margin: 0 auto;\r\n      display: flex;\r\n      justify-content: space-between;\r\n      align-items: center;\r\n      gap: 1rem;\r\n      font-size: 0.82rem;\r\n    }\r\n\r\n    .footer-inner strong { color: #eef1f3; text-transform: uppercase; }\r\n\r\n    \/* \u2500\u2500 Responsive \u2500\u2500 *\/\r\n    @media (max-width: 980px) {\r\n      .nav-links { display: none; }\r\n      .hero-inner, .studio { grid-template-columns: 1fr; }\r\n      .header-actions, .brand { min-width: auto; }\r\n      .service-grid, .pricing-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }\r\n      .steps { grid-template-columns: repeat(2, minmax(0, 1fr)); }\r\n    }\r\n\r\n    @media (max-width: 640px) {\r\n      .topbar { font-size: 0.7rem; }\r\n      .nav-wrap { min-height: 66px; padding: 0 1rem; }\r\n      .brand-mark { width: 36px; height: 36px; }\r\n      .brand-copy strong { font-size: 0.88rem; }\r\n      .brand-copy span, .phone { display: none; }\r\n      .btn { min-height: 40px; padding: 0.62rem 0.78rem; font-size: 0.86rem; }\r\n      .hero-inner { padding-top: 2.5rem; }\r\n      .service-grid, .pricing-grid, .proof-grid, .steps, .quote-form { grid-template-columns: 1fr; }\r\n      .preview-card, .garage-art { min-height: 320px; }\r\n      .studio { gap: 0.85rem; }\r\n      .panel { padding: 0.9rem; }\r\n      .footer-inner { flex-direction: column; align-items: flex-start; }\r\n      section { padding: 2rem 1rem; }\r\n    }\r\n  <\/style>\r\n<\/head>\r\n<body>\r\n\r\n\r\n\r\n  <main id=\"top\">\r\n    <section class=\"hero\">\r\n      <div class=\"hero-inner\">\r\n        <div>\r\n          <div class=\"eyebrow\"><span class=\"pulse\" aria-hidden=\"true\"><\/span>Local Brisbane installers<\/div>\r\n          <h1>Premium Epoxy Floors. <span>Affordable Rates.<\/span><\/h1>\r\n          <p class=\"hero-copy\">Transform a dusty garage, patio, showroom, or workshop concrete slab into a durable, high-gloss floor \u2014 with a finish you can preview before booking.<\/p>\r\n          <div class=\"proof-grid\" aria-label=\"Service highlights\">\r\n            <div class=\"proof-item\"><span class=\"icon\">&#10003;<\/span>3-day Rapid Application<\/div>\r\n            <div class=\"proof-item\"><span class=\"icon\">&#10003;<\/span>5\u201310 Year Local Warranty<\/div>\r\n            <div class=\"proof-item\"><span class=\"icon\">&#10003;<\/span>Non-Slip Matte &amp; Gloss Options<\/div>\r\n            <div class=\"proof-item\"><span class=\"icon\">&#10003;<\/span>No Hidden Travel Fees<\/div>\r\n            <div class=\"proof-item\"><span class=\"icon\">&#10003;<\/span>Metallic Finish Options<\/div>\r\n            <div class=\"proof-item\"><span class=\"icon\">&#10003;<\/span>Free Site Measure<\/div>\r\n          <\/div>\r\n          <div class=\"hero-actions\">\r\n            <a class=\"btn btn-primary\" href=\"#visualizer\">Try the Visualizer<\/a>\r\n            <a class=\"btn btn-secondary\" href=\"#services\">View Finishes<\/a>\r\n          <\/div>\r\n        <\/div>\r\n\r\n        <div class=\"preview-card\" aria-label=\"Epoxy floor preview\">\r\n          <img decoding=\"async\" class=\"garage-art\" src=\"https:\/\/affordableepoxyflooring.com.au\/wp-content\/uploads\/2026\/06\/matte-epoxy-flooring.png\" alt=\"Matte epoxy flooring preview\"\/>\r\n          <div class=\"preview-label\">\r\n            <div>\r\n              <strong>Signature Urban Gloss Grey<\/strong>\r\n              <span>Metallic flake finish preview<\/span>\r\n            <\/div>\r\n            <span class=\"tag\">POPULAR<\/span>\r\n          <\/div>\r\n        <\/div>\r\n      <\/div>\r\n    <\/section>\r\n\r\n    <div class=\"trust-strip\">\r\n      <p>Residential &amp; commercial concrete coating specialists<\/p>\r\n      <div class=\"trust-list\">\r\n        <span>Brisbane<\/span>\r\n        <span>Sunshine<\/span>\r\n        <span>Ipswich<\/span>\r\n        <span>Gold Coast<\/span>\r\n      <\/div>\r\n    <\/div>\r\n\r\n    <section id=\"services\">\r\n      <div class=\"section-inner\">\r\n        <div class=\"section-head\">\r\n          <h2>Architectural Coating Finishes<\/h2>\r\n          <p>Choose a practical coating system for how the space is used, then preview the colour and texture in the live visualizer.<\/p>\r\n        <\/div>\r\n        <div class=\"service-grid\">\r\n          <article class=\"service-card\">\r\n            <h3>Metallic Gloss Finish<\/h3>\r\n            <p>Flowing metallic pigments suspended in a premium resin layer, sealed under a high-gloss polyaspartic topcoat for a mirror-like depth.<\/p>\r\n            <div class=\"meta-row\"><span>Garages &amp; showrooms<\/span><strong>From $55\/m\u00b2<\/strong><\/div>\r\n          <\/article>\r\n          <article class=\"service-card\">\r\n            <h3>Flake Multi-Coat<\/h3>\r\n            <p>Decorative vinyl flakes broadcast into commercial resin and locked under a durable polyaspartic topcoat \u2014 available in matte or gloss.<\/p>\r\n            <div class=\"meta-row\"><span>Garages &amp; patios<\/span><strong>From $49\/m\u00b2<\/strong><\/div>\r\n          <\/article>\r\n          <article class=\"service-card\">\r\n            <h3>Solid Industrial<\/h3>\r\n            <p>A seamless monolithic finish for studios, retail spaces, workshops, and clean modern home conversions. High-build for heavy traffic.<\/p>\r\n            <div class=\"meta-row\"><span>Studios &amp; retail<\/span><strong>From $42\/m\u00b2<\/strong><\/div>\r\n          <\/article>\r\n          <article class=\"service-card\">\r\n            <h3>Commercial Slip-Resistant<\/h3>\r\n            <p>Aggregate-infused coatings built for foot traffic, machinery, chemical exposure, and wet-area grip. AS 4586-compliant ratings available.<\/p>\r\n            <div class=\"meta-row\"><span>Commercial sites<\/span><strong>From $55\/m\u00b2<\/strong><\/div>\r\n          <\/article>\r\n        <\/div>\r\n      <\/div>\r\n    <\/section>\r\n\r\n    <section id=\"visualizer\" class=\"visualizer-section\">\r\n      <div class=\"section-inner\">\r\n        <div class=\"section-head\">\r\n          <span class=\"tag\">LIVE STUDIO<\/span>\r\n          <h2 style=\"margin-top: .85rem; color:#fff;\">Floor Finish Visualizer<\/h2>\r\n          <p>Upload a photo of your space, choose a finish, then click the floor to auto-detect the slab area and preview the coating in real time.<\/p>\r\n        <\/div>\r\n\r\n        <div class=\"studio\">\r\n          <aside class=\"panel\" aria-label=\"Visualizer controls\">\r\n            <div class=\"control-group\">\r\n              <div class=\"control-label\"><span>Step 1 \u2014 Upload your space<\/span><\/div>\r\n              <label class=\"upload-box\">\r\n                <input id=\"floor-upload\" type=\"file\" accept=\"image\/*\">\r\n                <span>\r\n                  <strong>Choose an image file<\/strong>\r\n                  <span id=\"upload-label\">Garage, patio, showroom, or workshop photo<\/span>\r\n                <\/span>\r\n              <\/label>\r\n            <\/div>\r\n\r\n            <div class=\"control-group\">\r\n              <div class=\"control-label\"><span>Step 2 \u2014 Pick a finish<\/span><\/div>\r\n              <div class=\"segmented\" role=\"tablist\" aria-label=\"Finish groups\">\r\n                <button class=\"segment active\" type=\"button\" data-group=\"metallic\">Metallic<\/button>\r\n                <button class=\"segment\" type=\"button\" data-group=\"standard\">Standard<\/button>\r\n                <button class=\"segment\" type=\"button\" data-group=\"premium\">Premium<\/button>\r\n              <\/div>\r\n              <div id=\"finish-list\" class=\"finish-list\"><\/div>\r\n            <\/div>\r\n\r\n            <div class=\"control-group\">\r\n              <div class=\"control-label\"><span>Coating opacity<\/span><strong id=\"opacity-val\">76%<\/strong><\/div>\r\n              <input id=\"coat-opacity\" type=\"range\" min=\"25\" max=\"95\" value=\"76\">\r\n            <\/div>\r\n\r\n            <div class=\"control-group\">\r\n              <div class=\"control-label\"><span>Detection tolerance<\/span><strong id=\"tolerance-val\">22<\/strong><\/div>\r\n              <div class=\"range-stack\">\r\n                <input id=\"detect-tolerance\" type=\"range\" min=\"12\" max=\"72\" value=\"22\">\r\n                <div>\r\n                  <div class=\"control-label\"><span>Brush size<\/span><strong id=\"brush-size-val\">28<\/strong><\/div>\r\n                  <input id=\"brush-size\" type=\"range\" min=\"10\" max=\"70\" value=\"28\">\r\n                <\/div>\r\n                <div class=\"mode-grid\" aria-label=\"Mask editing tools\">\r\n                  <button class=\"mode-button active\" type=\"button\" data-mode=\"detect\">Detect<\/button>\r\n                  <button class=\"mode-button\" type=\"button\" data-mode=\"add\">Add Brush<\/button>\r\n                  <button class=\"mode-button\" type=\"button\" data-mode=\"erase\">Erase Brush<\/button>\r\n                  <button class=\"mode-button\" type=\"button\" data-mode=\"polygon\">Polygon<\/button>\r\n                  <button class=\"mode-button\" type=\"button\" data-mode=\"pan\" style=\"grid-column: 1 \/ -1;\">Pan \/ Move<\/button>\r\n                <\/div>\r\n              <\/div>\r\n            <\/div>\r\n\r\n            <div class=\"small-actions\">\r\n              <button id=\"undo-mask\" class=\"btn btn-ghost\" type=\"button\">Undo<\/button>\r\n              <button id=\"clean-mask\" class=\"btn btn-ghost\" type=\"button\">Clean Edges<\/button>\r\n              <button id=\"reset-mask\" class=\"btn btn-ghost\" type=\"button\">Reset Mask<\/button>\r\n              <button id=\"clear-mask\" class=\"btn btn-ghost\" type=\"button\">Clear Mask<\/button>\r\n            <\/div>\r\n          <\/aside>\r\n\r\n          <div class=\"canvas-shell\">\r\n            <div class=\"canvas-toolbar\">\r\n              <span id=\"visualizer-status\">Click a visible floor patch to auto-detect the mask. Use Add or Erase brush to refine around furniture.<\/span>\r\n              <div class=\"zoom-controls\">\r\n                <button class=\"zoom-btn\" id=\"zoom-out\" type=\"button\" title=\"Zoom out\">\u2212<\/button>\r\n                <span id=\"zoom-level\">100%<\/span>\r\n                <button class=\"zoom-btn\" id=\"zoom-in\" type=\"button\" title=\"Zoom in\">+<\/button>\r\n                <button class=\"zoom-btn\" id=\"zoom-reset\" type=\"button\" title=\"Reset zoom\">\u22a1<\/button>\r\n              <\/div>\r\n              <strong id=\"active-finish-name\">Black Gold<\/strong>\r\n            <\/div>\r\n            <div class=\"canvas-wrap\">\r\n              <canvas id=\"visualizer-canvas\" width=\"900\" height=\"620\" aria-label=\"Epoxy floor visualizer canvas\"><\/canvas>\r\n            <\/div>\r\n          <\/div>\r\n        <\/div>\r\n      <\/div>\r\n    <\/section>\r\n\r\n    <section id=\"process\">\r\n      <div class=\"section-inner\">\r\n        <div class=\"section-head\">\r\n          <h2>Four-Step Installation Process<\/h2>\r\n          <p>The coating is only as good as the preparation underneath it. This is the workflow behind every gloss finish.<\/p>\r\n        <\/div>\r\n        <div class=\"steps\">\r\n          <article class=\"step\">\r\n            <div class=\"step-num\">01<\/div>\r\n            <h3>Diamond Grind<\/h3>\r\n            <p>Concrete is mechanically opened so the coating bonds to a clean, profiled surface \u2014 not just paint on top.<\/p>\r\n          <\/article>\r\n          <article class=\"step\">\r\n            <div class=\"step-num\">02<\/div>\r\n            <h3>Repair &amp; Prime<\/h3>\r\n            <p>Cracks, pits, and chips are filled before a moisture-aware base coat is applied and fully cured.<\/p>\r\n          <\/article>\r\n          <article class=\"step\">\r\n            <div class=\"step-num\">03<\/div>\r\n            <h3>Broadcast Finish<\/h3>\r\n            <p>Flake, solid colour, or metallic effects are layered to full saturation according to the selected system.<\/p>\r\n          <\/article>\r\n          <article class=\"step\">\r\n            <div class=\"step-num\">04<\/div>\r\n            <h3>Seal &amp; Cure<\/h3>\r\n            <p>A UV-stable gloss topcoat adds high-sheen depth, chemical resistance, and long-term durability.<\/p>\r\n          <\/article>\r\n        <\/div>\r\n      <\/div>\r\n    <\/section>\r\n\r\n    <section id=\"pricing\">\r\n      <div class=\"section-inner\">\r\n        <div class=\"section-head\">\r\n          <h2>Simple Pricing Estimates<\/h2>\r\n          <p>Use these ranges to budget your project before a measured site quote \u2014 all prices include surface prep and topcoat.<\/p>\r\n        <\/div>\r\n        <div class=\"pricing-grid\">\r\n          <article class=\"price-card\">\r\n            <h3>Single Garage<\/h3>\r\n            <div class=\"price\">$1,350 <small>est.<\/small><\/div>\r\n            <p>For smaller home footprints or utility rooms around 18 m\u00b2.<\/p>\r\n            <ul class=\"feature-list\">\r\n              <li><span class=\"icon\">&#10003;<\/span>Diamond grinding included<\/li>\r\n              <li><span class=\"icon\">&#10003;<\/span>Solid or flake finish options<\/li>\r\n              <li><span class=\"icon\">&#10003;<\/span>Standard moisture barrier<\/li>\r\n              <li><span class=\"icon\">&#10003;<\/span>Gloss or matte topcoat<\/li>\r\n            <\/ul>\r\n          <\/article>\r\n          <article class=\"price-card featured\">\r\n            <h3>Double Garage<\/h3>\r\n            <div class=\"price\">$2,400 <small>est.<\/small><\/div>\r\n            <p>The most popular Brisbane double lockup garage package, around 36 m\u00b2.<\/p>\r\n            <ul class=\"feature-list\">\r\n              <li><span class=\"icon\">&#10003;<\/span>Full architectural flake blend<\/li>\r\n              <li><span class=\"icon\">&#10003;<\/span>Scratch-resistant gloss topcoat<\/li>\r\n              <li><span class=\"icon\">&#10003;<\/span>Concrete crack patching<\/li>\r\n              <li><span class=\"icon\">&#10003;<\/span>Metallic finish upgrade available<\/li>\r\n            <\/ul>\r\n          <\/article>\r\n          <article class=\"price-card\">\r\n            <h3>Commercial<\/h3>\r\n            <div class=\"price\">$55 <small>\/ m\u00b2<\/small><\/div>\r\n            <p>Scaled warehouse, showroom, workshop, and retail concrete coating solutions.<\/p>\r\n            <ul class=\"feature-list\">\r\n              <li><span class=\"icon\">&#10003;<\/span>Slip-resistant aggregate options<\/li>\r\n              <li><span class=\"icon\">&#10003;<\/span>Chemical-resistant formulation<\/li>\r\n              <li><span class=\"icon\">&#10003;<\/span>Custom colour consultation<\/li>\r\n              <li><span class=\"icon\">&#10003;<\/span>High-gloss metallic finishes<\/li>\r\n            <\/ul>\r\n          <\/article>\r\n        <\/div>\r\n      <\/div>\r\n    <\/section>\r\n\r\n    <section id=\"quote\" class=\"quote-section\">\r\n      <div class=\"section-inner\">\r\n        <div class=\"section-head\">\r\n          <h2 style=\"color: #fff;\">Request a Fixed Quote<\/h2>\r\n          <p>Send through your project details and the team will confirm preparation requirements, finish options, and per-square-metre pricing.<\/p>\r\n        <\/div>\r\n       <div class=\"forminator-ui forminator-custom-form forminator-custom-form-86 forminator-design--default  forminator_ajax\" data-forminator-render=\"0\" data-form=\"forminator-module-86\" data-uid=\"6a2d2af2215d1\"><br\/><\/div><form\n\t\t\t\tid=\"forminator-module-86\"\n\t\t\t\tclass=\"forminator-ui forminator-custom-form forminator-custom-form-86 forminator-design--default  forminator_ajax\"\n\t\t\t\tmethod=\"post\"\n\t\t\t\tdata-forminator-render=\"0\"\n\t\t\t\tdata-form-id=\"86\"\n\t\t\t\t data-color-option=\"theme\" data-design=\"default\" data-grid=\"open\" style=\"display: none;\"\n\t\t\t\tdata-uid=\"6a2d2af2215d1\"\n\t\t\t><div role=\"alert\" aria-live=\"polite\" class=\"forminator-response-message forminator-error\" aria-hidden=\"true\"><\/div><div class=\"forminator-row\"><div id=\"name-1\" class=\"forminator-field-name forminator-col forminator-col-6 \"><div class=\"forminator-field\"><label for=\"forminator-field-name-1_6a2d2af2215d1\" id=\"forminator-field-name-1_6a2d2af2215d1-label\" class=\"forminator-label\">First Name <span class=\"forminator-required\">*<\/span><\/label><input type=\"text\" name=\"name-1\" value=\"\" placeholder=\"John Smith\" id=\"forminator-field-name-1_6a2d2af2215d1\" class=\"forminator-input forminator-name--field\" aria-required=\"true\" autocomplete=\"name\" \/><\/div><\/div><div id=\"phone-1\" class=\"forminator-field-phone forminator-col forminator-col-6 \"><div class=\"forminator-field\"><label for=\"forminator-field-phone-1_6a2d2af2215d1\" id=\"forminator-field-phone-1_6a2d2af2215d1-label\" class=\"forminator-label\">Phone Number<\/label><input type=\"text\" name=\"phone-1\" value=\"\" placeholder=\"1400000\" id=\"forminator-field-phone-1_6a2d2af2215d1\" class=\"forminator-input forminator-field--phone\" data-required=\"\" aria-required=\"false\" autocomplete=\"off\" \/><\/div><\/div><\/div><div class=\"forminator-row\"><div id=\"text-1\" class=\"forminator-field-text forminator-col forminator-col-6 \"><div class=\"forminator-field\"><label for=\"forminator-field-text-1_6a2d2af2215d1\" id=\"forminator-field-text-1_6a2d2af2215d1-label\" class=\"forminator-label\">Suburb<\/label><input type=\"text\" name=\"text-1\" value=\"\" placeholder=\"\" id=\"forminator-field-text-1_6a2d2af2215d1\" class=\"forminator-input forminator-name--field\" data-required=\"\" \/><\/div><\/div><div id=\"select-1\" class=\"forminator-field-select forminator-col forminator-col-6 \"><div class=\"forminator-field\"><label for=\"forminator-form-86__field--select-1_6a2d2af2215d1\" id=\"forminator-form-86__field--select-1_6a2d2af2215d1-label\" class=\"forminator-label\">Space type<\/label><select  id=\"forminator-form-86__field--select-1_6a2d2af2215d1\" class=\"forminator-select--field forminator-select2 forminator-select2-multiple\" data-required=\"\" name=\"select-1\" data-default-value=\"\" data-hidden-behavior=\"zero\" data-placeholder=\"\" data-search=\"false\" data-search-placeholder=\"\" data-checkbox=\"false\" data-allow-clear=\"false\" aria-labelledby=\"forminator-form-86__field--select-1_6a2d2af2215d1-label\"><option value=\"one\"  data-calculation=\"0\">Double garage floor<\/option><option value=\"two\"  data-calculation=\"0\">Single garage or patio<\/option><option value=\"Commercial-workshop\"  data-calculation=\"0\">Commercial workshop<\/option><option value=\"Showroom-or-retail\"  data-calculation=\"0\">Showroom or retail<\/option><\/select><\/div><\/div><\/div><input type=\"hidden\" name=\"referer_url\" value=\"\" \/><div class=\"forminator-row forminator-row-last\"><div class=\"forminator-col\"><div class=\"forminator-field\"><button class=\"forminator-button forminator-button-submit\">Get My Free Pricing Estimate<\/button><\/div><\/div><\/div><input type=\"hidden\" id=\"forminator_nonce\" name=\"forminator_nonce\" value=\"86829240fe\" \/><input type=\"hidden\" name=\"_wp_http_referer\" value=\"\/index.php?rest_route=%2Fwp%2Fv2%2Fpages%2F22\" \/><input type=\"hidden\" name=\"form_id\" value=\"86\"><input type=\"hidden\" name=\"page_id\" value=\"22\"><input type=\"hidden\" name=\"form_type\" value=\"default\"><input type=\"hidden\" name=\"current_url\" value=\"https:\/\/affordableepoxyflooring.com.au\/\"><input type=\"hidden\" name=\"render_id\" value=\"0\"><input type=\"hidden\" name=\"action\" value=\"forminator_submit_form_custom-forms\"><\/form>\r\n      <\/div>\r\n    <\/section>\r\n  <\/main>\r\n\r\n\r\n\r\n  <script>\r\n    const finishes = {\r\n      standard: [\r\n        { name: \"Tuxedo\", color: \"#555d65\", type: \"flake\", detail: \"black, white & grey flake\" },\r\n        { name: \"Fog\", color: \"#aeb4b9\", type: \"flake\", detail: \"soft grey flake\" },\r\n        { name: \"Midnight\", color: \"#2f343b\", type: \"flake\", detail: \"dark architectural\" },\r\n        { name: \"California Grey\", color: \"#7b858d\", type: \"flake\", detail: \"balanced neutral\" }\r\n      ],\r\n      premium: [\r\n        { name: \"Carrara\", color: \"#d9d5ca\", type: \"flake\", detail: \"stone-inspired light\" },\r\n        { name: \"Granite\", color: \"#8d877f\", type: \"flake\", detail: \"dense premium blend\" },\r\n        { name: \"Riverside\", color: \"#768e92\", type: \"flake\", detail: \"cool grey-blue\" },\r\n        { name: \"Coastline\", color: \"#b8a386\", type: \"flake\", detail: \"warm coastal tone\" }\r\n      ],\r\n      metallic: [\r\n        { name: \"Black Gold\", color: \"#5b4a30\", type: \"metallic\", detail: \"deep metallic gold\" },\r\n        { name: \"Ocean Blue\", color: \"#245b75\", type: \"metallic\", detail: \"blue movement\" },\r\n        { name: \"Silver Ghost\", color: \"#b9c0c5\", type: \"metallic\", detail: \"silver pearl\" },\r\n        { name: \"White Marble\", color: \"#e3e0d8\", type: \"metallic\", detail: \"bright marble\" }\r\n      ]\r\n    };\r\n\r\n    const canvas = document.getElementById(\"visualizer-canvas\");\r\n    const ctx = canvas.getContext(\"2d\");\r\n    const uploadInput = document.getElementById(\"floor-upload\");\r\n    const uploadLabel = document.getElementById(\"upload-label\");\r\n    const opacityInput = document.getElementById(\"coat-opacity\");\r\n    const opacityVal = document.getElementById(\"opacity-val\");\r\n    const statusDisplay = document.getElementById(\"visualizer-status\");\r\n    const finishList = document.getElementById(\"finish-list\");\r\n    const activeFinishName = document.getElementById(\"active-finish-name\");\r\n    const zoomLevelDisplay = document.getElementById(\"zoom-level\");\r\n    const segmentButtons = [...document.querySelectorAll(\".segment\")];\r\n    const modeButtons = [...document.querySelectorAll(\".mode-button\")];\r\n    const toleranceInput = document.getElementById(\"detect-tolerance\");\r\n    const toleranceVal = document.getElementById(\"tolerance-val\");\r\n    const brushSizeInput = document.getElementById(\"brush-size\");\r\n    const brushSizeVal = document.getElementById(\"brush-size-val\");\r\n\r\n    let activeGroup = \"metallic\";\r\n    let activeFinish = finishes.metallic[0];\r\n    let uploadedImage = null;\r\n    let opacity = Number(opacityInput.value) \/ 100;\r\n    let tolerance = Number(toleranceInput.value);\r\n    let brushSize = Number(brushSizeInput.value);\r\n    let toolMode = \"detect\";\r\n    let points = [];\r\n    let draggingIndex = -1;\r\n    let isPainting = false;\r\n    let lastBrushPoint = null;\r\n    let detectDragStart = null;\r\n    let detectDidDrag = false;\r\n    let maskHistory = [];\r\n    let maskCanvas = document.createElement(\"canvas\");\r\n    let maskCtx = maskCanvas.getContext(\"2d\");\r\n    let baseCanvas = document.createElement(\"canvas\");\r\n    let baseCtx = baseCanvas.getContext(\"2d\");\r\n    let overlayCanvas = document.createElement(\"canvas\");\r\n    let overlayCtx = overlayCanvas.getContext(\"2d\");\r\n\r\n    \/\/ Zoom \/ pan state\r\n    let zoom = 1;\r\n    let viewOriginX = 0, viewOriginY = 0;\r\n    const MIN_ZOOM = 1, MAX_ZOOM = 12;\r\n    let isPanning = false;\r\n    let panStartCpx = 0, panStartCpy = 0;\r\n    let panStartOriginX = 0, panStartOriginY = 0;\r\n    let spaceHeld = false;\r\n    \/\/ Pinch tracking\r\n    const activePointers = new Map();\r\n    let lastPinchDist = 0;\r\n\r\n    \/\/ \u2500\u2500 Zoom helpers \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\r\n\r\n    function clampViewOrigin() {\r\n      const maxX = Math.max(0, canvas.width * (1 - 1 \/ zoom));\r\n      const maxY = Math.max(0, canvas.height * (1 - 1 \/ zoom));\r\n      viewOriginX = Math.max(0, Math.min(maxX, viewOriginX));\r\n      viewOriginY = Math.max(0, Math.min(maxY, viewOriginY));\r\n    }\r\n\r\n    function updateZoomDisplay() {\r\n      zoomLevelDisplay.textContent = Math.round(zoom * 100) + \"%\";\r\n    }\r\n\r\n    function zoomAt(cpx, cpy, factor) {\r\n      const imgX = cpx \/ zoom + viewOriginX;\r\n      const imgY = cpy \/ zoom + viewOriginY;\r\n      zoom = Math.max(MIN_ZOOM, Math.min(MAX_ZOOM, zoom * factor));\r\n      viewOriginX = imgX - cpx \/ zoom;\r\n      viewOriginY = imgY - cpy \/ zoom;\r\n      clampViewOrigin();\r\n      updateZoomDisplay();\r\n      draw();\r\n    }\r\n\r\n    function resetZoom() {\r\n      zoom = 1; viewOriginX = 0; viewOriginY = 0;\r\n      updateZoomDisplay();\r\n      draw();\r\n    }\r\n\r\n    \/\/ Canvas-pixel coordinates (before image-space conversion)\r\n    function getCanvasPixelPoint(event) {\r\n      const rect = canvas.getBoundingClientRect();\r\n      return {\r\n        x: (event.clientX - rect.left) * (canvas.width \/ rect.width),\r\n        y: (event.clientY - rect.top) * (canvas.height \/ rect.height)\r\n      };\r\n    }\r\n\r\n    \/\/ Image-space coordinates (accounts for zoom + pan)\r\n    function getCanvasPoint(event) {\r\n      const cp = getCanvasPixelPoint(event);\r\n      return { x: cp.x \/ zoom + viewOriginX, y: cp.y \/ zoom + viewOriginY };\r\n    }\r\n\r\n    \/\/ \u2500\u2500 Core helpers \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\r\n\r\n    function defaultPoints() {\r\n      return [\r\n        { x: canvas.width * 0.12, y: canvas.height * 0.57 },\r\n        { x: canvas.width * 0.88, y: canvas.height * 0.57 },\r\n        { x: canvas.width * 0.98, y: canvas.height * 0.96 },\r\n        { x: canvas.width * 0.02, y: canvas.height * 0.96 }\r\n      ];\r\n    }\r\n\r\n    function syncWorkingCanvases() {\r\n      [maskCanvas, baseCanvas, overlayCanvas].forEach((item) => {\r\n        item.width = canvas.width;\r\n        item.height = canvas.height;\r\n      });\r\n    }\r\n\r\n    const isTouchPrimary = navigator.maxTouchPoints > 0;\r\n\r\n    function setToolMode(mode) {\r\n      toolMode = mode;\r\n      modeButtons.forEach((button) => button.classList.toggle(\"active\", button.dataset.mode === mode));\r\n      const messages = {\r\n        detect: isTouchPrimary\r\n          ? \"Zoom in first (+), then tap the floor to detect. Drag to brush-paint.\"\r\n          : \"Click to auto-detect a floor area. Drag to brush-paint \u2014 use brush size to control width.\",\r\n        add: \"Add Brush active. Paint over floor areas the detector missed.\",\r\n        erase: \"Erase Brush active. Paint over beds, cabinets, or walls to remove coating.\",\r\n        polygon: \"Polygon mode active. Click points or drag gold handles for manual fallback.\",\r\n        pan: isTouchPrimary\r\n          ? \"Pan \/ Move active. Drag to scroll. Pinch to zoom.\"\r\n          : \"Pan \/ Move active. Drag to scroll the view. Use scroll wheel or +\/\u2212 to zoom.\"\r\n      };\r\n      statusDisplay.textContent = messages[mode] || \"\";\r\n      canvas.classList.toggle(\"pan-mode\", mode === \"pan\");\r\n      draw();\r\n    }\r\n\r\n    function clearMask() {\r\n      maskCtx.clearRect(0, 0, maskCanvas.width, maskCanvas.height);\r\n    }\r\n\r\n    function saveMaskHistory() {\r\n      if (!maskCanvas.width || !maskCanvas.height) return;\r\n      maskHistory.push(maskCtx.getImageData(0, 0, maskCanvas.width, maskCanvas.height));\r\n      if (maskHistory.length > 18) maskHistory.shift();\r\n    }\r\n\r\n    function undoMask() {\r\n      const previous = maskHistory.pop();\r\n      if (!previous) { statusDisplay.textContent = \"Nothing to undo yet.\"; return; }\r\n      maskCtx.putImageData(previous, 0, 0);\r\n      statusDisplay.textContent = \"Mask edit undone.\";\r\n      draw();\r\n    }\r\n\r\n    function hasMaskPixels() {\r\n      const data = maskCtx.getImageData(0, 0, maskCanvas.width, maskCanvas.height).data;\r\n      for (let i = 3; i < data.length; i += 160) { if (data[i] > 0) return true; }\r\n      return false;\r\n    }\r\n\r\n    function applyPolygonToMask() {\r\n      clearMask();\r\n      if (points.length < 3) return;\r\n      maskCtx.save();\r\n      maskCtx.fillStyle = \"#fff\";\r\n      maskCtx.beginPath();\r\n      maskCtx.moveTo(points[0].x, points[0].y);\r\n      points.slice(1).forEach((point) => maskCtx.lineTo(point.x, point.y));\r\n      maskCtx.closePath();\r\n      maskCtx.fill();\r\n      maskCtx.restore();\r\n    }\r\n\r\n    function resetDefaultMask() {\r\n      points = defaultPoints();\r\n      applyPolygonToMask();\r\n    }\r\n\r\n    function paintMask(point, mode) {\r\n      maskCtx.save();\r\n      maskCtx.globalCompositeOperation = mode === \"erase\" ? \"destination-out\" : \"source-over\";\r\n      maskCtx.strokeStyle = \"#fff\";\r\n      maskCtx.fillStyle = \"#fff\";\r\n      maskCtx.lineWidth = brushSize * 2;\r\n      maskCtx.lineCap = \"round\";\r\n      maskCtx.lineJoin = \"round\";\r\n      maskCtx.beginPath();\r\n      if (lastBrushPoint) {\r\n        maskCtx.moveTo(lastBrushPoint.x, lastBrushPoint.y);\r\n        maskCtx.lineTo(point.x, point.y);\r\n        maskCtx.stroke();\r\n      } else {\r\n        maskCtx.arc(point.x, point.y, brushSize, 0, Math.PI * 2);\r\n        maskCtx.fill();\r\n      }\r\n      maskCtx.restore();\r\n      lastBrushPoint = point;\r\n    }\r\n\r\n    function cleanMaskEdges() {\r\n      const width = maskCanvas.width;\r\n      const height = maskCanvas.height;\r\n      const image = maskCtx.getImageData(0, 0, width, height);\r\n      const data = image.data;\r\n      const src = new Uint8Array(width * height);\r\n      const out = new Uint8Array(width * height);\r\n\r\n      for (let i = 0; i < src.length; i++) { src[i] = data[i * 4 + 3] > 80 ? 1 : 0; }\r\n\r\n      for (let y = 1; y < height - 1; y++) {\r\n        for (let x = 1; x < width - 1; x++) {\r\n          const index = y * width + x;\r\n          let count = 0;\r\n          for (let oy = -1; oy <= 1; oy++) {\r\n            for (let ox = -1; ox <= 1; ox++) { count += src[(y + oy) * width + x + ox]; }\r\n          }\r\n          out[index] = src[index] ? count >= 4 : count >= 6;\r\n        }\r\n      }\r\n\r\n      const visited = new Uint8Array(width * height);\r\n      const queue = new Int32Array(width * height);\r\n      let largestComponent = [];\r\n\r\n      for (let start = 0; start < out.length; start++) {\r\n        if (!out[start] || visited[start]) continue;\r\n        let head = 0, tail = 0;\r\n        const component = [];\r\n        queue[tail++] = start;\r\n        visited[start] = 1;\r\n        while (head < tail) {\r\n          const pixel = queue[head++];\r\n          component.push(pixel);\r\n          const x = pixel % width;\r\n          const neighbors = [pixel - 1, pixel + 1, pixel - width, pixel + width];\r\n          for (const next of neighbors) {\r\n            if (next < 0 || next >= out.length || visited[next] || !out[next]) continue;\r\n            const nextX = next % width;\r\n            if ((next === pixel - 1 && x === 0) || (next === pixel + 1 && x === width - 1)) continue;\r\n            visited[next] = 1;\r\n            queue[tail++] = next;\r\n          }\r\n        }\r\n        if (component.length > largestComponent.length) largestComponent = component;\r\n      }\r\n\r\n      data.fill(0);\r\n      const keepAllThreshold = Math.max(1200, width * height * 0.012);\r\n      if (largestComponent.length < keepAllThreshold) {\r\n        for (let i = 0; i < out.length; i++) {\r\n          if (!out[i]) continue;\r\n          data[i * 4] = 255; data[i * 4 + 1] = 255; data[i * 4 + 2] = 255; data[i * 4 + 3] = 255;\r\n        }\r\n      } else {\r\n        largestComponent.forEach((pixel) => {\r\n          data[pixel * 4] = 255; data[pixel * 4 + 1] = 255; data[pixel * 4 + 2] = 255; data[pixel * 4 + 3] = 255;\r\n        });\r\n      }\r\n\r\n      maskCtx.putImageData(image, 0, 0);\r\n      statusDisplay.textContent = \"Mask cleaned. Use Add Brush if any floor patch was removed.\";\r\n      draw();\r\n    }\r\n\r\n    function autoDetectFromPoint(seedPoint) {\r\n      const width = canvas.width;\r\n      const height = canvas.height;\r\n      const seedX = Math.max(0, Math.min(width - 1, Math.round(seedPoint.x)));\r\n      const seedY = Math.max(0, Math.min(height - 1, Math.round(seedPoint.y)));\r\n      \/\/ baseCanvas always holds the scene at 1:1 \u2014 safe to read regardless of zoom\r\n      const source = baseCtx.getImageData(0, 0, width, height).data;\r\n      const mask = maskCtx.getImageData(0, 0, width, height);\r\n      const maskData = mask.data;\r\n      const seedIndex = (seedY * width + seedX) * 4;\r\n      const seedR = source[seedIndex];\r\n      const seedG = source[seedIndex + 1];\r\n      const seedB = source[seedIndex + 2];\r\n      const limit = tolerance * tolerance;\r\n      const visited = new Uint8Array(width * height);\r\n      const queue = new Int32Array(width * height);\r\n      let head = 0, tail = 0, filled = 0;\r\n\r\n      saveMaskHistory();\r\n      queue[tail++] = seedY * width + seedX;\r\n      visited[seedY * width + seedX] = 1;\r\n\r\n      while (head < tail) {\r\n        const pixel = queue[head++];\r\n        const x = pixel % width;\r\n        const index = pixel * 4;\r\n        const dr = source[index] - seedR;\r\n        const dg = source[index + 1] - seedG;\r\n        const db = source[index + 2] - seedB;\r\n        if (dr * dr + dg * dg + db * db > limit) continue;\r\n        maskData[index] = 255; maskData[index + 1] = 255; maskData[index + 2] = 255; maskData[index + 3] = 255;\r\n        filled++;\r\n        const neighbors = [pixel - 1, pixel + 1, pixel - width, pixel + width];\r\n        for (const next of neighbors) {\r\n          if (next < 0 || next >= width * height || visited[next]) continue;\r\n          const nextX = next % width;\r\n          if ((next === pixel - 1 && nextX === width - 1) || (next === pixel + 1 && nextX === 0)) continue;\r\n          visited[next] = 1;\r\n          queue[tail++] = next;\r\n        }\r\n      }\r\n\r\n      \/\/ Guard: if fill covered more than 68% of the image it almost certainly bled into walls\/background\r\n      const maxSafePixels = Math.floor(width * height * 0.68);\r\n      if (filled > maxSafePixels) {\r\n        \/\/ Restore the state saved before this fill\r\n        const saved = maskHistory[maskHistory.length - 1];\r\n        if (saved) maskCtx.putImageData(saved, 0, 0);\r\n        statusDisplay.textContent = isTouchPrimary\r\n          ? \"Too much matched \u2014 zoom in first (+), then tap the floor area directly.\"\r\n          : \"Too much area matched. Lower the tolerance and click on the floor specifically.\";\r\n        draw();\r\n        return;\r\n      }\r\n\r\n      maskCtx.putImageData(mask, 0, 0);\r\n      statusDisplay.textContent = filled < 120\r\n        ? \"Only a tiny area matched. Raise tolerance or click another floor patch.\"\r\n        : \"Floor area detected. Click more patches to expand, or use Erase Brush to refine around objects.\";\r\n      draw();\r\n    }\r\n\r\n    function renderFinishList() {\r\n      finishList.innerHTML = \"\";\r\n      finishes[activeGroup].forEach((finish) => {\r\n        const button = document.createElement(\"button\");\r\n        button.className = `finish-button${finish.name === activeFinish.name ? \" active\" : \"\"}`;\r\n        button.type = \"button\";\r\n        button.innerHTML = `\r\n          <span class=\"swatch ${finish.type}\" style=\"--swatch: ${finish.color}\"><\/span>\r\n          <span>\r\n            <span class=\"finish-title\">${finish.name}<\/span>\r\n            <span class=\"finish-type\">${finish.detail}<\/span>\r\n          <\/span>\r\n          <span class=\"select-mark\">${finish.name === activeFinish.name ? \"&#10003;\" : \"\"}<\/span>\r\n        `;\r\n        button.addEventListener(\"click\", () => {\r\n          activeFinish = finish;\r\n          activeFinishName.textContent = finish.name;\r\n          renderFinishList();\r\n          draw();\r\n        });\r\n        finishList.appendChild(button);\r\n      });\r\n    }\r\n\r\n    \/\/ \u2500\u2500 Drawing (context-parameterised so base scene can go to baseCanvas) \u2500\u2500\r\n\r\n    function drawDemoRoom(c) {\r\n      const width = canvas.width;\r\n      const height = canvas.height;\r\n\r\n      c.fillStyle = \"#2e353a\";\r\n      c.fillRect(0, 0, width, height);\r\n\r\n      const wallHeight = height * 0.55;\r\n      const grad = c.createLinearGradient(0, 0, 0, wallHeight);\r\n      grad.addColorStop(0, \"#dfe4e8\");\r\n      grad.addColorStop(1, \"#b7c0c8\");\r\n      c.fillStyle = grad;\r\n      c.fillRect(width * 0.07, height * 0.07, width * 0.86, wallHeight);\r\n\r\n      const floorGrad = c.createLinearGradient(0, wallHeight, width, height);\r\n      floorGrad.addColorStop(0, \"#6b737a\");\r\n      floorGrad.addColorStop(0.4, \"#3a4045\");\r\n      floorGrad.addColorStop(1, \"#252a2e\");\r\n      c.fillStyle = floorGrad;\r\n      c.beginPath();\r\n      c.moveTo(width * 0.07, wallHeight); c.lineTo(width * 0.93, wallHeight);\r\n      c.lineTo(width, height); c.lineTo(0, height);\r\n      c.closePath(); c.fill();\r\n\r\n      c.strokeStyle = \"#8a9299\"; c.lineWidth = 2.5;\r\n      c.beginPath(); c.moveTo(width * 0.07, wallHeight); c.lineTo(width * 0.93, wallHeight); c.stroke();\r\n\r\n      const glossGrad = c.createLinearGradient(0, wallHeight, 0, wallHeight + height * 0.18);\r\n      glossGrad.addColorStop(0, \"rgba(255,255,255,0.32)\");\r\n      glossGrad.addColorStop(1, \"rgba(255,255,255,0)\");\r\n      c.fillStyle = glossGrad;\r\n      c.beginPath();\r\n      c.moveTo(width * 0.07, wallHeight); c.lineTo(width * 0.93, wallHeight);\r\n      c.lineTo(width * 0.85, wallHeight + height * 0.18); c.lineTo(width * 0.15, wallHeight + height * 0.18);\r\n      c.closePath(); c.fill();\r\n\r\n      c.fillStyle = \"rgba(255,255,255,0.1)\";\r\n      c.beginPath();\r\n      c.moveTo(width * 0.22, wallHeight + 4); c.lineTo(width * 0.78, wallHeight + 4);\r\n      c.lineTo(width * 0.72, wallHeight + 28); c.lineTo(width * 0.28, wallHeight + 28);\r\n      c.closePath(); c.fill();\r\n\r\n      c.strokeStyle = \"rgba(255,255,255,.14)\"; c.lineWidth = 1.5;\r\n      [[0],[1],[2],[3]].forEach(([i]) => {\r\n        c.beginPath();\r\n        if (i === 0) { c.moveTo(width * 0.5, wallHeight); c.lineTo(width * 0.34, height); }\r\n        if (i === 1) { c.moveTo(width * 0.5, wallHeight); c.lineTo(width * 0.66, height); }\r\n        if (i === 2) { c.moveTo(width * 0.07, wallHeight); c.lineTo(0, height); }\r\n        if (i === 3) { c.moveTo(width * 0.93, wallHeight); c.lineTo(width, height); }\r\n        c.stroke();\r\n      });\r\n\r\n      c.fillStyle = \"rgba(255,255,255,.88)\";\r\n      c.fillRect(width * 0.13, height * 0.15, width * 0.18, height * 0.16);\r\n      c.fillRect(width * 0.38, height * 0.15, width * 0.24, height * 0.16);\r\n      c.fillRect(width * 0.69, height * 0.15, width * 0.18, height * 0.16);\r\n\r\n      c.fillStyle = \"rgba(255,255,255,0.5)\";\r\n      c.fillRect(width * 0.13, height * 0.15, width * 0.18, height * 0.045);\r\n      c.fillRect(width * 0.38, height * 0.15, width * 0.24, height * 0.045);\r\n      c.fillRect(width * 0.69, height * 0.15, width * 0.18, height * 0.045);\r\n    }\r\n\r\n    function drawImageCover(image, c) {\r\n      const scale = Math.max(canvas.width \/ image.width, canvas.height \/ image.height);\r\n      const w = image.width * scale, h = image.height * scale;\r\n      c.drawImage(image, (canvas.width - w) \/ 2, (canvas.height - h) \/ 2, w, h);\r\n    }\r\n\r\n    function polygonPath() {\r\n      if (points.length < 2) return;\r\n      ctx.beginPath();\r\n      ctx.moveTo(points[0].x, points[0].y);\r\n      points.slice(1).forEach((point) => ctx.lineTo(point.x, point.y));\r\n      ctx.closePath();\r\n    }\r\n\r\n    function drawFlakes(targetCtx) {\r\n      const seed = activeFinish.name.length * 11;\r\n      for (let i = 0; i < 850; i++) {\r\n        const x = (Math.sin(i * 999 + seed) * 0.5 + 0.5) * canvas.width;\r\n        const y = (Math.cos(i * 421 + seed) * 0.5 + 0.5) * canvas.height;\r\n        const size = ((i % 5) + 1) * 0.7;\r\n        targetCtx.fillStyle = i % 11 === 0 ? \"#c7a15a\" : i % 3 === 0 ? \"#111317\" : \"#f5f6f7\";\r\n        targetCtx.globalAlpha = i % 11 === 0 ? 0.6 : 0.42;\r\n        targetCtx.fillRect(x, y, size, size);\r\n      }\r\n    }\r\n\r\n    function drawMetallic(targetCtx) {\r\n      targetCtx.globalAlpha = 0.28;\r\n      for (let i = 0; i < 18; i++) {\r\n        targetCtx.beginPath();\r\n        targetCtx.strokeStyle = i % 2 ? \"#ffffff\" : \"#0d1114\";\r\n        targetCtx.lineWidth = 18 + (i % 5) * 9;\r\n        targetCtx.moveTo(-80, canvas.height * (i \/ 18));\r\n        targetCtx.bezierCurveTo(canvas.width * 0.22, canvas.height * 0.1 + i * 18, canvas.width * 0.68, canvas.height * 0.8 - i * 11, canvas.width + 80, canvas.height * ((i + 3) \/ 18));\r\n        targetCtx.stroke();\r\n      }\r\n    }\r\n\r\n    function drawGlossSheen(targetCtx) {\r\n      targetCtx.globalAlpha = 0.22;\r\n      const glossGrad = targetCtx.createLinearGradient(0, 0, 0, canvas.height * 0.35);\r\n      glossGrad.addColorStop(0, \"rgba(255,255,255,0.9)\");\r\n      glossGrad.addColorStop(0.4, \"rgba(255,255,255,0.3)\");\r\n      glossGrad.addColorStop(1, \"rgba(255,255,255,0)\");\r\n      targetCtx.fillStyle = glossGrad;\r\n      targetCtx.fillRect(0, 0, canvas.width, canvas.height);\r\n      targetCtx.globalAlpha = 1;\r\n    }\r\n\r\n    function drawOverlay() {\r\n      if (!hasMaskPixels()) return;\r\n\r\n      overlayCtx.clearRect(0, 0, overlayCanvas.width, overlayCanvas.height);\r\n      overlayCtx.globalAlpha = opacity;\r\n      overlayCtx.fillStyle = activeFinish.color;\r\n      overlayCtx.fillRect(0, 0, canvas.width, canvas.height);\r\n\r\n      if (activeFinish.type === \"flake\") drawFlakes(overlayCtx);\r\n      if (activeFinish.type === \"metallic\") drawMetallic(overlayCtx);\r\n\r\n      drawGlossSheen(overlayCtx);\r\n\r\n      overlayCtx.globalAlpha = 0.16;\r\n      const shadow = overlayCtx.createLinearGradient(0, canvas.height * 0.48, 0, canvas.height);\r\n      shadow.addColorStop(0, \"#ffffff\");\r\n      shadow.addColorStop(0.25, \"transparent\");\r\n      shadow.addColorStop(1, \"#000000\");\r\n      overlayCtx.fillStyle = shadow;\r\n      overlayCtx.fillRect(0, 0, canvas.width, canvas.height);\r\n\r\n      overlayCtx.globalAlpha = 1;\r\n      overlayCtx.globalCompositeOperation = \"destination-in\";\r\n      overlayCtx.drawImage(maskCanvas, 0, 0);\r\n      overlayCtx.globalCompositeOperation = \"source-over\";\r\n      \/\/ Note: caller (draw) composites overlayCanvas onto ctx with zoom transform\r\n    }\r\n\r\n    function drawHandles() {\r\n      if (toolMode !== \"polygon\") return;\r\n      \/\/ Scale handle geometry by 1\/zoom so handles appear at a constant screen size\r\n      const r = 8 \/ zoom;\r\n      const lw = 2 \/ zoom;\r\n      const fs = Math.round(10 \/ zoom);\r\n      if (points.length > 1) {\r\n        ctx.save();\r\n        ctx.strokeStyle = \"rgba(199,161,90,.78)\";\r\n        ctx.lineWidth = lw;\r\n        polygonPath();\r\n        ctx.stroke();\r\n        ctx.restore();\r\n      }\r\n      points.forEach((point, index) => {\r\n        ctx.beginPath();\r\n        ctx.arc(point.x, point.y, r, 0, Math.PI * 2);\r\n        ctx.fillStyle = \"#c7a15a\";\r\n        ctx.fill();\r\n        ctx.lineWidth = lw;\r\n        ctx.strokeStyle = \"#ffffff\";\r\n        ctx.stroke();\r\n        ctx.fillStyle = \"#202124\";\r\n        ctx.font = `700 ${fs}px system-ui`;\r\n        ctx.textAlign = \"center\";\r\n        ctx.textBaseline = \"middle\";\r\n        ctx.fillText(String(index + 1), point.x, point.y);\r\n      });\r\n    }\r\n\r\n    function draw() {\r\n      \/\/ 1. Refresh baseCanvas at 1:1 (flood fill always reads from here)\r\n      baseCtx.clearRect(0, 0, baseCanvas.width, baseCanvas.height);\r\n      if (uploadedImage) drawImageCover(uploadedImage, baseCtx);\r\n      else drawDemoRoom(baseCtx);\r\n\r\n      \/\/ 2. Compute overlay into overlayCanvas at 1:1\r\n      drawOverlay();\r\n\r\n      \/\/ 3. Composite onto visible canvas with zoom\/pan transform\r\n      ctx.clearRect(0, 0, canvas.width, canvas.height);\r\n      ctx.save();\r\n      ctx.setTransform(zoom, 0, 0, zoom, -viewOriginX * zoom, -viewOriginY * zoom);\r\n      ctx.drawImage(baseCanvas, 0, 0);\r\n      if (hasMaskPixels()) ctx.drawImage(overlayCanvas, 0, 0);\r\n      drawHandles();\r\n      ctx.restore();\r\n    }\r\n\r\n    function nearestPointIndex(point) {\r\n      return points.findIndex((existing) => Math.hypot(existing.x - point.x, existing.y - point.y) < 18 \/ zoom);\r\n    }\r\n\r\n    \/\/ \u2500\u2500 Pointer events \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\r\n\r\n    canvas.addEventListener(\"pointerdown\", (event) => {\r\n      activePointers.set(event.pointerId, getCanvasPixelPoint(event));\r\n\r\n      \/\/ Middle-mouse or pan mode or space held \u2192 start panning\r\n      if (event.button === 1 || toolMode === \"pan\" || spaceHeld) {\r\n        isPanning = true;\r\n        const cp = getCanvasPixelPoint(event);\r\n        panStartCpx = cp.x; panStartCpy = cp.y;\r\n        panStartOriginX = viewOriginX; panStartOriginY = viewOriginY;\r\n        canvas.setPointerCapture(event.pointerId);\r\n        canvas.classList.add(\"is-panning\");\r\n        return;\r\n      }\r\n\r\n      const point = getCanvasPoint(event);\r\n      if (toolMode === \"detect\") {\r\n        detectDragStart = point;\r\n        detectDidDrag = false;\r\n        lastBrushPoint = null;\r\n        isPainting = true;\r\n        canvas.setPointerCapture(event.pointerId);\r\n        return;\r\n      }\r\n      if (toolMode === \"add\" || toolMode === \"erase\") {\r\n        isPainting = true;\r\n        lastBrushPoint = null;\r\n        saveMaskHistory();\r\n        canvas.setPointerCapture(event.pointerId);\r\n        paintMask(point, toolMode);\r\n        draw();\r\n        return;\r\n      }\r\n      const index = nearestPointIndex(point);\r\n      if (index >= 0) {\r\n        draggingIndex = index;\r\n        canvas.setPointerCapture(event.pointerId);\r\n      } else {\r\n        if (points.length >= 10) points.shift();\r\n        points.push(point);\r\n        saveMaskHistory();\r\n        applyPolygonToMask();\r\n        statusDisplay.textContent = \"Point added. Drag any gold handle to refine the floor boundary.\";\r\n        draw();\r\n      }\r\n    });\r\n\r\n    canvas.addEventListener(\"pointermove\", (event) => {\r\n      \/\/ Two-finger pinch zoom\r\n      if (activePointers.size === 2 && activePointers.has(event.pointerId)) {\r\n        activePointers.set(event.pointerId, getCanvasPixelPoint(event));\r\n        const pts = [...activePointers.values()];\r\n        const dist = Math.hypot(pts[1].x - pts[0].x, pts[1].y - pts[0].y);\r\n        if (lastPinchDist > 0) {\r\n          const cx = (pts[0].x + pts[1].x) \/ 2;\r\n          const cy = (pts[0].y + pts[1].y) \/ 2;\r\n          zoomAt(cx, cy, dist \/ lastPinchDist);\r\n        }\r\n        lastPinchDist = dist;\r\n        return;\r\n      }\r\n\r\n      if (isPainting && toolMode === \"detect\") {\r\n        const point = getCanvasPoint(event);\r\n        if (!detectDidDrag) {\r\n          if (Math.hypot(point.x - detectDragStart.x, point.y - detectDragStart.y) * zoom > 4) {\r\n            detectDidDrag = true;\r\n            saveMaskHistory();\r\n          }\r\n        }\r\n        if (detectDidDrag) { paintMask(point, \"add\"); draw(); }\r\n        return;\r\n      }\r\n\r\n      if (isPanning) {\r\n        const cp = getCanvasPixelPoint(event);\r\n        viewOriginX = panStartOriginX - (cp.x - panStartCpx) \/ zoom;\r\n        viewOriginY = panStartOriginY - (cp.y - panStartCpy) \/ zoom;\r\n        clampViewOrigin();\r\n        draw();\r\n        return;\r\n      }\r\n      if (isPainting && (toolMode === \"add\" || toolMode === \"erase\")) {\r\n        paintMask(getCanvasPoint(event), toolMode);\r\n        draw();\r\n        return;\r\n      }\r\n      if (draggingIndex < 0) return;\r\n      points[draggingIndex] = getCanvasPoint(event);\r\n      applyPolygonToMask();\r\n      statusDisplay.textContent = \"Adjusting floor mask boundary.\";\r\n      draw();\r\n    });\r\n\r\n    canvas.addEventListener(\"pointerup\", (event) => {\r\n      activePointers.delete(event.pointerId);\r\n      lastPinchDist = 0;\r\n      if (toolMode === \"detect\" && isPainting && !detectDidDrag && detectDragStart) {\r\n        autoDetectFromPoint(detectDragStart);\r\n      }\r\n      draggingIndex = -1; isPainting = false; isPanning = false;\r\n      lastBrushPoint = null; detectDragStart = null; detectDidDrag = false;\r\n      canvas.classList.remove(\"is-panning\");\r\n    });\r\n    canvas.addEventListener(\"pointercancel\", (event) => {\r\n      activePointers.delete(event.pointerId);\r\n      lastPinchDist = 0;\r\n      draggingIndex = -1; isPainting = false; isPanning = false;\r\n      lastBrushPoint = null; detectDragStart = null; detectDidDrag = false;\r\n      canvas.classList.remove(\"is-panning\");\r\n    });\r\n\r\n    \/\/ Scroll-wheel zoom (also covers trackpad pinch)\r\n    canvas.addEventListener(\"wheel\", (event) => {\r\n      event.preventDefault();\r\n      const cp = getCanvasPixelPoint(event);\r\n      const factor = event.deltaY < 0 ? 1.12 : 1 \/ 1.12;\r\n      zoomAt(cp.x, cp.y, factor);\r\n    }, { passive: false });\r\n\r\n    \/\/ Space + drag = temporary pan (like Photoshop)\r\n    document.addEventListener(\"keydown\", (e) => {\r\n      if (e.code === \"Space\" && !e.repeat && document.activeElement.tagName !== \"INPUT\" && document.activeElement.tagName !== \"SELECT\") {\r\n        spaceHeld = true;\r\n        canvas.classList.add(\"pan-mode\");\r\n        e.preventDefault();\r\n      }\r\n    });\r\n    document.addEventListener(\"keyup\", (e) => {\r\n      if (e.code === \"Space\") {\r\n        spaceHeld = false;\r\n        if (toolMode !== \"pan\") canvas.classList.remove(\"pan-mode\");\r\n      }\r\n    });\r\n\r\n    \/\/ \u2500\u2500 UI listeners \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\r\n\r\n    document.getElementById(\"zoom-in\").addEventListener(\"click\", () => zoomAt(canvas.width \/ 2, canvas.height \/ 2, 1.5));\r\n    document.getElementById(\"zoom-out\").addEventListener(\"click\", () => zoomAt(canvas.width \/ 2, canvas.height \/ 2, 1 \/ 1.5));\r\n    document.getElementById(\"zoom-reset\").addEventListener(\"click\", resetZoom);\r\n\r\n    uploadInput.addEventListener(\"change\", (event) => {\r\n      const file = event.target.files[0];\r\n      if (!file) return;\r\n      uploadLabel.textContent = file.name;\r\n      const reader = new FileReader();\r\n      reader.onload = () => {\r\n        const image = new Image();\r\n        image.onload = () => {\r\n          uploadedImage = image;\r\n          points = defaultPoints();\r\n          clearMask();\r\n          resetZoom();\r\n          setToolMode(\"detect\");\r\n          statusDisplay.textContent = \"Image loaded. Click a visible floor patch to auto-detect it.\";\r\n          draw();\r\n        };\r\n        image.src = reader.result;\r\n      };\r\n      reader.readAsDataURL(file);\r\n    });\r\n\r\n    opacityInput.addEventListener(\"input\", () => {\r\n      opacity = Number(opacityInput.value) \/ 100;\r\n      opacityVal.textContent = `${opacityInput.value}%`;\r\n      draw();\r\n    });\r\n\r\n    toleranceInput.addEventListener(\"input\", () => {\r\n      tolerance = Number(toleranceInput.value);\r\n      toleranceVal.textContent = toleranceInput.value;\r\n    });\r\n\r\n    brushSizeInput.addEventListener(\"input\", () => {\r\n      brushSize = Number(brushSizeInput.value);\r\n      brushSizeVal.textContent = brushSizeInput.value;\r\n    });\r\n\r\n    modeButtons.forEach((button) => { button.addEventListener(\"click\", () => setToolMode(button.dataset.mode)); });\r\n\r\n    document.getElementById(\"undo-mask\").addEventListener(\"click\", undoMask);\r\n    document.getElementById(\"clean-mask\").addEventListener(\"click\", () => { saveMaskHistory(); cleanMaskEdges(); });\r\n\r\n    segmentButtons.forEach((button) => {\r\n      button.addEventListener(\"click\", () => {\r\n        activeGroup = button.dataset.group;\r\n        activeFinish = finishes[activeGroup][0];\r\n        activeFinishName.textContent = activeFinish.name;\r\n        segmentButtons.forEach((item) => item.classList.toggle(\"active\", item === button));\r\n        renderFinishList();\r\n        draw();\r\n      });\r\n    });\r\n\r\n    document.getElementById(\"reset-mask\").addEventListener(\"click\", () => {\r\n      saveMaskHistory();\r\n      resetDefaultMask();\r\n      setToolMode(\"polygon\");\r\n      statusDisplay.textContent = \"Floor mask reset to default polygon. Drag gold handles to adjust it.\";\r\n      draw();\r\n    });\r\n\r\n    document.getElementById(\"clear-mask\").addEventListener(\"click\", () => {\r\n      saveMaskHistory();\r\n      points = [];\r\n      clearMask();\r\n      setToolMode(\"detect\");\r\n      statusDisplay.textContent = \"Mask cleared. Click a visible floor patch to detect it again.\";\r\n      draw();\r\n    });\r\n\r\n    const quoteForm = document.getElementById(\"quote-form\");\r\n    if (quoteForm) {\r\n      quoteForm.addEventListener(\"submit\", (event) => {\r\n        event.preventDefault();\r\n        alert(\"Thanks! Your epoxy flooring pricing request has been submitted. The team will be in touch shortly.\");\r\n      });\r\n    }\r\n\r\n    syncWorkingCanvases();\r\n    resetDefaultMask();\r\n    renderFinishList();\r\n    draw();\r\n  <\/script>\r\n<\/body>\r\n<\/html>\t\t\t\t<\/div>\n\t\t\n<\/div>\n<div class=\"elementor-element elementor-element-0d2e103 e-con e-atomic-element e-flexbox-base e-083b727 \" data-id=\"0d2e103\" data-element_type=\"e-flexbox\" data-e-type=\"e-flexbox\" data-interaction-id=\"0d2e103\">\n    \t\t<div class=\"elementor-element elementor-element-d754aea elementor-widget elementor-widget-spacer\" data-id=\"d754aea\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"spacer.default\">\n\t\t\t\t\t\t\t<div class=\"elementor-spacer\">\n\t\t\t<div class=\"elementor-spacer-inner\"><\/div>\n\t\t<\/div>\n\t\t\t\t\t\t<\/div>\n\t\t\n<\/div>\n<div class=\"elementor-element elementor-element-aeb9963 e-con e-atomic-element e-flexbox-base e-22769f4 \" data-id=\"aeb9963\" data-element_type=\"e-flexbox\" data-e-type=\"e-flexbox\" data-interaction-id=\"aeb9963\">\n    \t\t\t<h2 data-interaction-id=\"6b98a37\" class=\"e-6b98a37-c50a646 e-heading-base\">GALLERY<\/h2>\n\t\t\n<\/div>\n<div class=\"elementor-element elementor-element-683ad22 e-flex e-con-boxed e-con e-parent\" data-id=\"683ad22\" 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-3ebcfd6 elementor-arrows-position-inside elementor-widget elementor-widget-image-carousel\" data-id=\"3ebcfd6\" data-element_type=\"widget\" data-e-type=\"widget\" data-settings=\"{&quot;navigation&quot;:&quot;arrows&quot;,&quot;slides_to_show&quot;:&quot;4&quot;,&quot;autoplay&quot;:&quot;yes&quot;,&quot;pause_on_hover&quot;:&quot;yes&quot;,&quot;pause_on_interaction&quot;:&quot;yes&quot;,&quot;autoplay_speed&quot;:5000,&quot;infinite&quot;:&quot;yes&quot;,&quot;speed&quot;:500,&quot;image_spacing_custom&quot;:{&quot;unit&quot;:&quot;px&quot;,&quot;size&quot;:20,&quot;sizes&quot;:[]},&quot;image_spacing_custom_tablet&quot;:{&quot;unit&quot;:&quot;px&quot;,&quot;size&quot;:&quot;&quot;,&quot;sizes&quot;:[]},&quot;image_spacing_custom_mobile&quot;:{&quot;unit&quot;:&quot;px&quot;,&quot;size&quot;:&quot;&quot;,&quot;sizes&quot;:[]}}\" data-widget_type=\"image-carousel.default\">\n\t\t\t\t\t\t\t<div class=\"elementor-image-carousel-wrapper swiper\" role=\"region\" aria-roledescription=\"carousel\" aria-label=\"Image Carousel\" dir=\"ltr\">\n\t\t\t<div class=\"elementor-image-carousel swiper-wrapper\" aria-live=\"off\">\n\t\t\t\t\t\t\t\t<div class=\"swiper-slide\" role=\"group\" aria-roledescription=\"slide\" aria-label=\"1 of 7\"><figure class=\"swiper-slide-inner\"><img decoding=\"async\" class=\"swiper-slide-image\" src=\"https:\/\/affordableepoxyflooring.com.au\/wp-content\/uploads\/elementor\/thumbs\/Black-Shiny-Epoxy-Flooring-1-ron3oousw7f7alrz07akrfpk5an7sq23ezeo4ijd1s.jpeg\" alt=\"Black Shiny Epoxy Flooring in Brisbane\" \/><\/figure><\/div><div class=\"swiper-slide\" role=\"group\" aria-roledescription=\"slide\" aria-label=\"2 of 7\"><figure class=\"swiper-slide-inner\"><img decoding=\"async\" class=\"swiper-slide-image\" src=\"https:\/\/affordableepoxyflooring.com.au\/wp-content\/uploads\/elementor\/thumbs\/WhatsApp-Image-2026-06-07-at-13.06.34-4-ron3z051vrjgoksns5s7mc0msht79602i13got8us0.jpeg\" alt=\"WhatsApp Image 2026-06-07 at 13.06.34 (4)\" \/><\/figure><\/div><div class=\"swiper-slide\" role=\"group\" aria-roledescription=\"slide\" aria-label=\"3 of 7\"><figure class=\"swiper-slide-inner\"><img decoding=\"async\" class=\"swiper-slide-image\" src=\"https:\/\/affordableepoxyflooring.com.au\/wp-content\/uploads\/elementor\/thumbs\/WhatsApp-Image-2026-06-07-at-13.06.33-ron3yxbjb9flpqwr8mkbwuq90c73m2ovhn508zd1ao.jpeg\" alt=\"WhatsApp Image 2026-06-07 at 13.06.33\" \/><\/figure><\/div><div class=\"swiper-slide\" role=\"group\" aria-roledescription=\"slide\" aria-label=\"4 of 7\"><figure class=\"swiper-slide-inner\"><img decoding=\"async\" class=\"swiper-slide-image\" src=\"https:\/\/affordableepoxyflooring.com.au\/wp-content\/uploads\/elementor\/thumbs\/WhatsApp-Image-2026-06-07-at-13.06.34-1-ron3pu7p8wzthg3wap65t59ua8zd7ema8o418ou1g0.jpeg\" alt=\"\" \/><\/figure><\/div><div class=\"swiper-slide\" role=\"group\" aria-roledescription=\"slide\" aria-label=\"5 of 7\"><figure class=\"swiper-slide-inner\"><img decoding=\"async\" class=\"swiper-slide-image\" src=\"https:\/\/affordableepoxyflooring.com.au\/wp-content\/uploads\/elementor\/thumbs\/WhatsApp-Image-2026-06-07-at-13.06.34-5-ron3z20q9fm1bspxh6lgrbjjz9jxok7j6aefnd62fk.jpeg\" alt=\"WhatsApp Image 2026-06-07 at 13.06.34 (5)\" \/><\/figure><\/div><div class=\"swiper-slide\" role=\"group\" aria-roledescription=\"slide\" aria-label=\"6 of 7\"><figure class=\"swiper-slide-inner\"><img decoding=\"async\" class=\"swiper-slide-image\" src=\"https:\/\/affordableepoxyflooring.com.au\/wp-content\/uploads\/elementor\/thumbs\/WhatsApp-Image-2026-06-07-at-13.06.34-ron3z5s30rr6m8kgv87z1alect1ejcmgit0dkh0hqo.jpeg\" alt=\"WhatsApp Image 2026-06-07 at 13.06.34\" \/><\/figure><\/div><div class=\"swiper-slide\" role=\"group\" aria-roledescription=\"slide\" aria-label=\"7 of 7\"><figure class=\"swiper-slide-inner\"><img decoding=\"async\" class=\"swiper-slide-image\" src=\"https:\/\/affordableepoxyflooring.com.au\/wp-content\/uploads\/elementor\/thumbs\/WhatsApp-Image-2026-06-07-at-13.06.34-3-ron3yz77oxi6cyu0xndl1u9673xu1gwc5wfz7ja8y8.jpeg\" alt=\"WhatsApp Image 2026-06-07 at 13.06.34 (3)\" \/><\/figure><\/div>\t\t\t<\/div>\n\t\t\t\t\t\t\t\t\t\t\t\t<div class=\"elementor-swiper-button elementor-swiper-button-prev\" role=\"button\" tabindex=\"0\">\n\t\t\t\t\t\t<svg aria-hidden=\"true\" class=\"e-font-icon-svg e-eicon-chevron-left\" viewBox=\"0 0 1000 1000\" xmlns=\"http:\/\/www.w3.org\/2000\/svg\"><path d=\"M646 125C629 125 613 133 604 142L308 442C296 454 292 471 292 487 292 504 296 521 308 533L604 854C617 867 629 875 646 875 663 875 679 871 692 858 704 846 713 829 713 812 713 796 708 779 692 767L438 487 692 225C700 217 708 204 708 187 708 171 704 154 692 142 675 129 663 125 646 125Z\"><\/path><\/svg>\t\t\t\t\t<\/div>\n\t\t\t\t\t<div class=\"elementor-swiper-button elementor-swiper-button-next\" role=\"button\" tabindex=\"0\">\n\t\t\t\t\t\t<svg aria-hidden=\"true\" class=\"e-font-icon-svg e-eicon-chevron-right\" viewBox=\"0 0 1000 1000\" xmlns=\"http:\/\/www.w3.org\/2000\/svg\"><path d=\"M696 533C708 521 713 504 713 487 713 471 708 454 696 446L400 146C388 133 375 125 354 125 338 125 325 129 313 142 300 154 292 171 292 187 292 204 296 221 308 233L563 492 304 771C292 783 288 800 288 817 288 833 296 850 308 863 321 871 338 875 354 875 371 875 388 867 400 854L696 533Z\"><\/path><\/svg>\t\t\t\t\t<\/div>\n\t\t\t\t\n\t\t\t\t\t\t\t\t\t<\/div>\n\t\t\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>Brisbane Epoxy Flooring Visualizer Local Brisbane installers Premium Epoxy Floors. Affordable Rates. Transform a dusty garage, patio, showroom, or workshop concrete slab into a durable, high-gloss floor \u2014 with a finish you can preview before booking. &#10003;3-day Rapid Application &#10003;5\u201310 Year Local Warranty &#10003;Non-Slip Matte &amp; Gloss Options &#10003;No Hidden Travel Fees &#10003;Metallic Finish Options [&hellip;]<\/p>\n","protected":false},"author":2,"featured_media":0,"parent":0,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"elementor_header_footer","meta":{"footnotes":""},"class_list":["post-22","page","type-page","status-publish","hentry"],"blocksy_meta":[],"_links":{"self":[{"href":"https:\/\/affordableepoxyflooring.com.au\/index.php?rest_route=\/wp\/v2\/pages\/22","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/affordableepoxyflooring.com.au\/index.php?rest_route=\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/affordableepoxyflooring.com.au\/index.php?rest_route=\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/affordableepoxyflooring.com.au\/index.php?rest_route=\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/affordableepoxyflooring.com.au\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=22"}],"version-history":[{"count":64,"href":"https:\/\/affordableepoxyflooring.com.au\/index.php?rest_route=\/wp\/v2\/pages\/22\/revisions"}],"predecessor-version":[{"id":131,"href":"https:\/\/affordableepoxyflooring.com.au\/index.php?rest_route=\/wp\/v2\/pages\/22\/revisions\/131"}],"wp:attachment":[{"href":"https:\/\/affordableepoxyflooring.com.au\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=22"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}