{"id":1253,"date":"2026-09-21T08:56:37","date_gmt":"2026-09-21T08:56:37","guid":{"rendered":"https:\/\/chachamatcha.ae\/?page_id=1253"},"modified":"2026-10-13T11:57:03","modified_gmt":"2026-10-13T11:57:03","slug":"catering","status":"publish","type":"page","link":"https:\/\/chachamatcha.ae\/ar\/catering\/","title":{"rendered":"Catering"},"content":{"rendered":"\t\t<div data-elementor-type=\"wp-page\" data-elementor-id=\"1253\" class=\"elementor elementor-1253\">\n\t\t\t\t<div class=\"elementor-element elementor-element-5e3e9a9 e-con-full e-flex e-con e-parent\" data-id=\"5e3e9a9\" data-element_type=\"container\" data-e-type=\"container\">\n\t\t\t\t<div class=\"elementor-element elementor-element-2a7acf0 elementor-widget elementor-widget-html\" data-id=\"2a7acf0\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"html.default\">\n\t\t\t\t\t<!doctype html>\n<html lang=\"en\">\n<head>\n<meta charset=\"utf-8\">\n<meta name=\"viewport\" content=\"width=device-width,initial-scale=1,viewport-fit=cover\">\n<title>Catering Event Booking<\/title>\n<style>\n:root{\n  --green:#76A866;--green-dark:#4F7547;--green-pale:#EEF5EA;\n  --cream:#FBF7E9;--ink:#2E352C;--muted:#7D857A;--line:#E1E6DE;\n  --brown:#4F7547;--danger:#B42318;--yellow:#FFF3C9;--white:#fff;\n}\n*{box-sizing:border-box}\nbody{margin:0;font-family:Inter,-apple-system,BlinkMacSystemFont,\"Segoe UI\",Roboto,Arial,sans-serif;background:var(--cream);color:var(--ink)}\nbutton,input,textarea,select{font:inherit}\nbutton{cursor:pointer}\n.app{min-height:100vh;padding:18px}\n.shell{max-width:1240px;margin:auto;background:#fff;border-radius:24px;overflow:hidden;display:grid;grid-template-columns:minmax(0,1.45fr) minmax(340px,.75fr);box-shadow:0 18px 55px rgba(50,70,46,.12)}\n.main{padding:38px 44px 44px}\n.side{background:linear-gradient(160deg,#F4F8F1,#E9F2E5);color:var(--ink);padding:44px 36px;border-left:1px solid var(--line)}\n.logoText{font-size:29px;line-height:.86;font-weight:900;color:var(--green);letter-spacing:-.05em}\n.logoText small{display:block;font-size:9px;line-height:1.4;letter-spacing:.16em;color:#7E8D78;margin-top:8px}\n.top{display:flex;align-items:center;justify-content:space-between;margin-bottom:32px}\n.secure{background:var(--green-pale);color:var(--green-dark);padding:9px 12px;border-radius:999px;font-size:10px;font-weight:800;letter-spacing:.08em;text-transform:uppercase}\n.steps{display:flex;align-items:center;gap:8px;margin-bottom:34px;overflow:auto;scrollbar-width:none}\n.steps::-webkit-scrollbar{display:none}\n.step{display:flex;align-items:center;gap:7px;white-space:nowrap;font-size:10px;font-weight:800;letter-spacing:.12em;color:#A9AFA7}\n.step i{font-style:normal;width:28px;height:28px;border:1px solid #D8DED5;border-radius:50%;display:grid;place-items:center;background:#fff}\n.step.active{color:var(--green-dark)} .step.active i{background:var(--green);border-color:var(--green);color:#fff}\n.step.done{color:var(--green-dark)} .step.done i{background:var(--green-pale);border-color:#C9DEC1;color:var(--green-dark)}\n.line{width:38px;height:1px;background:#DFE5DC;flex:0 0 38px}\n.panel{display:none}.panel.active{display:block}\n.eyebrow{font-size:11px;text-transform:uppercase;letter-spacing:.18em;font-weight:900;color:var(--green-dark);margin:0 0 8px}\nh2{font-size:clamp(30px,4vw,40px);line-height:1.07;letter-spacing:-.035em;margin:0 0 10px}\n.lead{font-size:14px;line-height:1.6;color:var(--muted);margin:0 0 28px}\n.label{display:block;font-size:11px;text-transform:uppercase;letter-spacing:.14em;font-weight:900;color:#657063;margin-bottom:9px}\n.field{margin-bottom:24px}.grid2{display:grid;grid-template-columns:1fr 1fr;gap:14px}\ninput,textarea,select,.dateDisplay{width:100%;min-height:52px;border:1px solid var(--line);border-radius:12px;background:#fff;color:var(--ink);padding:15px;outline:none}\ninput:focus,textarea:focus,select:focus,.dateDisplay:focus{border-color:var(--green);box-shadow:0 0 0 4px rgba(118,168,102,.12)}\ntextarea{min-height:96px;resize:vertical}.selectWrap{position:relative}.selectWrap:after{content:\"\u2304\";position:absolute;right:15px;top:50%;transform:translateY(-55%);pointer-events:none;color:var(--green-dark);font-weight:900}\nselect{appearance:none;padding-right:40px}\n.cards{display:grid;grid-template-columns:repeat(4,1fr);gap:10px}\n.pick,.cup,.custom{border:1px solid var(--line);background:#fff;border-radius:14px;text-align:left;color:var(--ink);transition:.15s;position:relative}\n.pick{padding:15px;min-height:102px}.pick .price{font-size:9px;text-transform:uppercase;letter-spacing:.12em;font-weight:900;color:#879083;margin-bottom:7px}.pick strong{font-size:14px}\n.pick.selected,.cup.selected{background:var(--green-pale);border-color:var(--green);box-shadow:inset 0 0 0 1px var(--green)}\n.pick.selected:after,.cup.selected:after{content:\"\u2713\";position:absolute;right:10px;top:9px;width:21px;height:21px;background:var(--green);color:#fff;border-radius:50%;display:grid;place-items:center;font-size:12px;font-weight:900}\n.cupGrid{display:grid;grid-template-columns:1fr 1fr;gap:13px}.cup{padding:20px}.cup h3{margin:0 0 8px;font-size:19px}.cup p{font-size:13px;color:var(--muted);line-height:1.5;margin:0 0 11px}.tier{font-size:13px;line-height:1.5;font-weight:800;color:var(--green-dark)}\n.badge{display:inline-flex;background:var(--green-pale);color:var(--green-dark);padding:5px 8px;border-radius:999px;font-size:10px}\n.qtyRow{display:flex;gap:13px;align-items:center;flex-wrap:wrap}.qty{display:grid;grid-template-columns:52px 92px 52px;border:1px solid var(--line);border-radius:12px;overflow:hidden}.qty button{border:0;background:#fff;color:var(--green-dark);font-size:22px}.qty input{border:0;border-left:1px solid var(--line);border-right:1px solid var(--line);border-radius:0;text-align:center;padding:10px}\n.pills{display:flex;gap:7px;flex-wrap:wrap}.pill{border:1px solid var(--line);background:#fff;border-radius:999px;padding:9px 13px;font-size:13px}\n.customGrid{display:grid;grid-template-columns:repeat(3,1fr);gap:11px}.custom{padding:17px;min-height:164px}.custom.selected{background:var(--green-dark);color:#fff;border-color:var(--green-dark)}.custom h3{font-size:16px;margin:0 0 8px}.custom p{font-size:12.5px;line-height:1.5;color:var(--muted);margin:0 0 12px}.custom.selected p{color:#DDE8D9}.cost{font-size:13px;font-weight:900}\n.option{display:flex;align-items:flex-start;gap:11px;border:1px solid var(--line);border-radius:14px;padding:15px;margin-top:11px}.option input{width:18px;height:18px;min-height:0;accent-color:var(--green);margin-top:1px}.option small{display:block;color:var(--muted);margin-top:4px}\n.slotTimer{display:none;align-items:center;justify-content:space-between;gap:12px;background:var(--green-pale);border:1px solid #D3E5CC;color:var(--green-dark);border-radius:12px;padding:13px 15px;margin-bottom:20px;font-size:13px}.slotTimer.show{display:flex}.slotTimer b{font-size:18px}.slotTimer.expired{background:#FFF4F2;border-color:#F1C7C2;color:var(--danger)}\n.review{border:1px solid var(--line);border-radius:15px;overflow:hidden}.reviewSec{padding:17px 19px;border-bottom:1px solid var(--line)}.reviewSec:last-child{border-bottom:0}.reviewSec h3{font-size:11px;letter-spacing:.13em;color:var(--green-dark);margin:0 0 9px}.rline{display:flex;justify-content:space-between;gap:16px;padding:5px 0;font-size:13.5px}.rline span:first-child{color:var(--muted)}.rline b{text-align:right}\n.termsSummary{background:var(--yellow);border-radius:12px;padding:18px 20px;margin-top:20px}.termsSummary h3{font-size:11px;letter-spacing:.14em;margin:0 0 12px}.termsSummary ul{padding-left:19px;margin:0 0 12px}.termsSummary li{font-size:13px;line-height:1.55;margin:7px 0}.termsLink{border:0;background:none;padding:0;text-decoration:underline;font-weight:800;color:var(--ink)}\n.checkRow{display:flex;gap:12px;align-items:flex-start;border:1px solid var(--line);border-radius:12px;padding:16px;margin-top:16px}.checkRow input{width:19px;height:19px;min-height:0;accent-color:var(--green);margin-top:2px}\n.error{display:none;color:var(--danger);font-size:12.5px;margin-top:9px}\n.nav{display:flex;justify-content:space-between;gap:12px;border-top:1px solid var(--line);padding-top:22px;margin-top:29px}.btn{border:0;border-radius:999px;min-height:49px;padding:13px 22px;font-weight:900}.primary{background:var(--green);color:#fff}.secondary{background:#F0F3EE;color:var(--green-dark)}.btn:disabled{opacity:.55;cursor:not-allowed}\n.summary h3{font-size:28px;margin:0 0 4px}.sub{font-size:10px;letter-spacing:.18em;text-transform:uppercase;color:var(--green-dark);margin-bottom:25px}.sumrow{display:flex;justify-content:space-between;gap:18px;padding:15px 0;border-bottom:1px dashed #CBD9C6;font-size:13.5px}.sumrow span:first-child{color:#687566}.sumrow span:last-child{font-weight:800;text-align:right}.priceBox{background:#FFFFFF;padding:16px;border:1px solid var(--line);border-radius:10px;margin-top:18px}.total{display:flex;justify-content:space-between;align-items:flex-end;padding-top:24px}.total small{font-size:10px;letter-spacing:.15em;text-transform:uppercase;color:#687566}.total b{font-size:30px;color:var(--green-dark)}\n.note{background:#FFFFFF;border:1px solid var(--line);border-radius:12px;padding:13px;margin-top:20px;font-size:12px;line-height:1.5;color:#667063}\n.depositBox{background:#FFFFFF;border:1px solid var(--line);border-radius:12px;padding:14px 16px;margin-top:18px}.depositRow{display:flex;justify-content:space-between;gap:16px;padding:5px 0;font-size:13px}.depositRow span{color:#687566}.depositRow b{text-align:right}.depositRow.payNow b{color:var(--green-dark)}\n.qtyPriceInfo{margin-top:14px;font-size:13px;line-height:1.5;color:var(--muted)}.qtyPriceInfo strong{color:var(--ink);font-weight:900}\n.signatureNotice{background:var(--yellow);border-radius:8px;padding:12px 14px;margin:0 0 14px;font-size:12.5px;line-height:1.45;color:var(--ink)}\n.signatureWrap{margin-top:28px}.signatureIntro{font-size:13px;color:var(--muted);margin:-2px 0 14px;line-height:1.55}.optionalTag{font-weight:600;text-transform:none;letter-spacing:0;color:var(--muted);margin-left:5px}.signatureGroup{margin-top:18px}.signatureGroupTitle{font-size:10px;text-transform:uppercase;letter-spacing:.15em;font-weight:900;color:var(--green-dark);margin:0 0 9px}.signatureGrid{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:10px}.signatureCard{border:1px solid var(--line);background:#fff;border-radius:13px;padding:10px;display:flex;flex-direction:column;gap:8px;align-items:stretch;text-align:left;position:relative;min-width:0;color:var(--ink)}.signatureCard img{width:100%;aspect-ratio:1.2\/1;object-fit:cover;border-radius:9px;background:var(--cream);display:block}.signatureCard .sigState{font-size:8px;text-transform:uppercase;letter-spacing:.12em;color:var(--green-dark);font-weight:900;margin-bottom:4px}.signatureCard strong{display:block;font-size:12.5px;line-height:1.25;margin-bottom:4px}.signatureCard p{font-size:10.5px;line-height:1.35;color:var(--muted);margin:0}.signatureCard.selected{background:var(--green-dark);border-color:var(--green-dark);color:#fff}.signatureCard.selected .sigState{color:#EAF3E5}.signatureCard.selected p{color:#DDE8D9}.signatureCard:disabled{opacity:.5;cursor:not-allowed}.signatureCount{font-size:12.5px;font-weight:900;color:var(--green-dark);margin-top:10px}.signatureEmpty{border:1px dashed var(--line);border-radius:12px;padding:14px;font-size:13px;color:var(--muted)}\n.payHero{background:var(--cream);border:1px solid #E8DEC1;border-radius:12px;padding:17px 20px;margin:0 0 24px}.payHeroTop{display:flex;justify-content:space-between;gap:18px;align-items:flex-start}.payHero .miniLabel{font-size:9px;text-transform:uppercase;letter-spacing:.16em;font-weight:900;color:var(--green-dark)}.payHero .heroAmount{font-size:30px;font-weight:900;line-height:1;color:var(--ink)}.payHero .heroAmount small{font-size:12px;font-weight:800}.payHero .heroSub{font-size:12px;color:var(--muted);margin-top:6px}.payHeroRemain{border-top:1px dashed #D8CEB4;margin-top:15px;padding-top:13px;display:flex;justify-content:space-between;gap:12px;font-size:12px}.payChoice{display:flex;align-items:center;gap:12px;border:1px solid var(--line);border-radius:12px;padding:14px 15px;margin:9px 0;background:#fff;cursor:pointer}.payChoice.selected{border-color:var(--green-dark);box-shadow:inset 0 0 0 1px var(--green-dark);background:var(--cream)}.payChoice input{width:18px;height:18px;min-height:0;accent-color:var(--green-dark);flex:0 0 auto}.payChoice .payCopy{flex:1;min-width:0}.payChoice strong{display:block;font-size:13.5px}.payChoice small{display:block;color:var(--muted);font-size:11.5px;margin-top:3px;line-height:1.4}.payChoice .choiceAmount{font-weight:900;font-size:14px;white-space:nowrap}.securePayBox{background:var(--cream);border-radius:12px;padding:18px;margin-top:20px;text-align:center;font-size:12px;line-height:1.55}.securePayBox strong{display:block;font-size:13px;margin-bottom:5px}\n.dateWrap{position:relative}.dateDisplay{display:flex;justify-content:space-between;align-items:center;text-align:left}.dateDisplay.placeholder{color:#969E94}.calendar{display:none;position:absolute;z-index:80;top:calc(100% + 8px);left:0;width:min(360px,92vw);background:#fff;border:1px solid var(--line);border-radius:16px;box-shadow:0 18px 45px rgba(50,70,46,.18);padding:14px}.calendar.open{display:block}.calHead{display:flex;align-items:center;justify-content:space-between;margin-bottom:12px}.calNav{width:36px;height:36px;border:0;border-radius:10px;background:var(--green-pale);color:var(--green-dark);font-size:18px}.week,.days{display:grid;grid-template-columns:repeat(7,1fr);gap:4px}.week span{text-align:center;font-size:10px;font-weight:900;color:#9AA299;padding:5px}.day{border:0;background:transparent;border-radius:10px;aspect-ratio:1;color:var(--ink);font-size:12px}.day:hover:not(:disabled){background:var(--green-pale)}.day.selected{background:var(--green);color:#fff;font-weight:900}.day:disabled{color:#C9CEC7;background:#F5F6F4;cursor:not-allowed;text-decoration:line-through}.day.unavailable{color:#B8BDB6;background:#F2F3F1;cursor:not-allowed;text-decoration:line-through;opacity:.72}.day.empty{visibility:hidden}.calLoading{grid-column:1\/-1;padding:22px 8px;text-align:center;color:var(--muted);font-size:12px;line-height:1.5}.calLoading b{display:block;color:var(--green-dark);margin-bottom:4px}\n.modal{display:none;position:fixed;z-index:99999;inset:0;background:rgba(23,28,22,.62);padding:18px;align-items:center;justify-content:center}.modal.open{display:flex}.modalCard{width:min(720px,100%);max-height:88vh;background:#fff;border-radius:18px;overflow:hidden;display:flex;flex-direction:column}.modalHead{display:flex;justify-content:space-between;align-items:center;padding:20px 22px;border-bottom:1px solid var(--line)}.modalHead h3{margin:0;font-size:21px}.close{border:0;background:var(--green-pale);color:var(--green-dark);width:38px;height:38px;border-radius:50%;font-size:21px}.modalBody{padding:22px;overflow:auto}.modalBody p,.modalBody li{font-size:14px;line-height:1.65}.modalBody ol{padding-left:22px}\n\n.timeWrap{position:relative}\n.timeDisplay{width:100%;min-height:52px;border:1px solid var(--line);border-radius:12px;background:#fff;color:var(--ink);padding:15px;display:flex;align-items:center;justify-content:space-between;text-align:left;outline:none}\n.timeDisplay.placeholder{color:#969E94}.timeDisplay:focus{border-color:var(--green);box-shadow:0 0 0 4px rgba(118,168,102,.12)}\n.timeIcon{font-size:18px;color:var(--green-dark)}\n.timePicker{display:none;position:absolute;z-index:85;top:calc(100% + 8px);right:0;width:min(430px,92vw);max-height:min(520px,70vh);overflow-y:auto;overscroll-behavior:contain;background:#fff;border:1px solid var(--line);border-radius:16px;box-shadow:0 18px 45px rgba(50,70,46,.18);padding:14px}\n.timePicker.open{display:block}.timePickerHead{display:flex;align-items:center;justify-content:space-between;margin-bottom:12px}.timePickerHead strong{font-size:15px}.timeClose{width:34px;height:34px;border:0;border-radius:50%;background:var(--green-pale);color:var(--green-dark);font-size:20px}\n.timeGrid{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:8px}.timeLoading{grid-column:1\/-1;border:1px solid var(--line);border-radius:12px;background:#F7F9F5;padding:18px 14px;text-align:center;color:var(--muted);font-size:12px}.timeLoading b{display:block;color:var(--green-dark);margin-bottom:4px}.timeSlot{border:1px solid var(--line);border-radius:10px;background:#fff;min-height:58px;padding:9px 7px;text-align:center;color:var(--ink)}.timeSlot strong{display:block;font-size:12.5px}.timeSlot small{display:block;margin-top:3px;font-size:9px;color:var(--muted)}.timeSlot:hover:not(:disabled){border-color:var(--green);background:var(--green-pale)}.timeSlot.selected{border-color:var(--green);background:var(--green-dark);color:#fff}.timeSlot.selected small{color:#DDE8D9}.timeSlot:disabled{background:#F5F6F4;color:#B5BBB2;cursor:not-allowed}.timeSlot:disabled small{color:#B5BBB2}.timeHint{margin-top:10px;font-size:10.5px;color:var(--muted);text-align:center}\n\n.mobileSummary,.mobileBar{display:none}\n@media(max-width:1000px){.mobileSummary{display:none!important}.app{padding:10px}.shell{grid-template-columns:1fr;border-radius:18px}.side{display:none}.main{padding:24px 22px 96px}.mobileSummary{display:block;background:var(--green-dark);color:#fff;border-radius:15px;padding:14px 15px;margin-bottom:22px}.mobileSummary .row{display:flex;justify-content:space-between;align-items:center}.mobileSummary small{color:#EADCCE}.mobileSummary b{font-size:20px}.cards{grid-template-columns:repeat(3,1fr)}.mobileBar{display:flex;position:fixed;z-index:9999;left:10px;right:10px;bottom:max(10px,env(safe-area-inset-bottom));background:var(--green-dark);border-radius:16px;padding:10px 10px 10px 14px;align-items:center;justify-content:space-between;box-shadow:0 12px 32px rgba(43,35,31,.3)}.mobileBar small{display:block;color:#EADCCE;font-size:9px;text-transform:uppercase;letter-spacing:.12em}.mobileBar b{color:#fff;font-size:19px}.mobileBar .btn{background:var(--green);color:#fff;min-height:44px;padding:10px 16px}}\n@media(max-width:700px){.main{padding:20px 15px 94px}.signatureGrid{grid-template-columns:repeat(2,minmax(0,1fr))!important;gap:8px}.grid2,.cupGrid{grid-template-columns:1fr}.customGrid{grid-template-columns:1fr}.cards{grid-template-columns:1fr 1fr}.line{width:18px;flex-basis:18px}.step{font-size:9px}.step i{width:25px;height:25px}.nav .btn{flex:1}.calendar{position:fixed;left:12px;right:12px;top:50%;transform:translateY(-50%);width:auto}}\n\n\/* ===== MOBILE-FIRST REFINEMENT ===== *\/\nhtml,body{max-width:100%;overflow-x:hidden}\n@media(max-width:1000px){\n  body{background:#fff}\n  .app{padding:0;min-height:100dvh}\n  .shell{\n    display:block;\n    width:100%;\n    max-width:none;\n    margin:0;\n    border-radius:0;\n    box-shadow:none;\n    overflow:visible;\n  }\n  .side{display:none!important}\n  .main{\n    width:100%;\n    max-width:100%;\n    padding:18px 16px calc(110px + env(safe-area-inset-bottom));\n    overflow:visible;\n  }\n  .top{\n    margin:0 0 18px;\n    justify-content:flex-end;\n    min-height:32px;\n  }\n  .top>div:first-child{display:none}\n  .secure{\n    padding:8px 10px;\n    font-size:9px;\n    letter-spacing:.06em;\n    white-space:nowrap;\n  }\n\n  .mobileSummary{\n    display:none!important;\n    margin:0 0 18px;\n    padding:14px 15px;\n    border-radius:14px;\n    background:linear-gradient(145deg,var(--green-dark),#3f6339);\n    box-shadow:0 8px 24px rgba(79,117,71,.18);\n  }\n  .mobileSummary .row{gap:12px}\n  .mobileSummary small{font-size:10px;line-height:1.35}\n  .mobileSummary b{font-size:20px;line-height:1.1}\n\n  .steps{\n    display:grid;\n    grid-template-columns:repeat(5,minmax(0,1fr));\n    gap:5px;\n    width:100%;\n    margin:0 0 24px;\n    overflow:visible;\n  }\n  .line{display:none}\n  .step{\n    min-width:0;\n    justify-content:center;\n    flex-direction:column;\n    gap:5px;\n    text-align:center;\n    font-size:8px;\n    letter-spacing:.06em;\n    white-space:normal;\n    line-height:1.15;\n  }\n  .step i{\n    width:29px;\n    height:29px;\n    font-size:11px;\n  }\n\n  .slotTimer{\n    margin:0 0 18px;\n    padding:12px 13px;\n    border-radius:12px;\n    font-size:12px;\n  }\n  .slotTimer b{font-size:17px;flex:0 0 auto}\n\n  h2{\n    font-size:30px;\n    line-height:1.06;\n    margin-bottom:9px;\n  }\n  .eyebrow{font-size:10px;margin-bottom:7px}\n  .lead{\n    font-size:13.5px;\n    line-height:1.55;\n    margin-bottom:22px;\n  }\n\n  .grid2,.cupGrid,.customGrid{\n    grid-template-columns:1fr!important;\n    gap:11px;\n  }\n  .field{margin-bottom:20px}\n  .label{font-size:10px;margin-bottom:8px}\n\n  input,textarea,select,.dateDisplay{\n    min-height:54px;\n    font-size:16px; \/* prevents iOS zoom *\/\n    border-radius:12px;\n    padding:14px;\n  }\n  textarea{min-height:94px}\n\n  .cards{\n    grid-template-columns:1fr 1fr!important;\n    gap:9px;\n  }\n  .pick{\n    min-width:0;\n    min-height:92px;\n    padding:13px 12px;\n    border-radius:12px;\n  }\n  .pick strong{\n    font-size:13px;\n    line-height:1.25;\n    word-break:normal;\n  }\n  .pick .price{\n    font-size:8.5px;\n    letter-spacing:.08em;\n    line-height:1.25;\n  }\n\n  .cup{\n    min-height:0;\n    padding:16px;\n    border-radius:13px;\n  }\n  .cup h3{font-size:18px;padding-right:28px}\n  .cup p{font-size:12.5px}\n  .tier{font-size:12.5px}\n\n  .qtyRow{\n    display:block;\n  }\n  .qty{\n    width:100%;\n    grid-template-columns:54px 1fr 54px;\n    margin-bottom:11px;\n  }\n  .qty input{width:100%;min-width:0}\n  .pills{\n    display:grid;\n    grid-template-columns:repeat(5,1fr);\n    gap:6px;\n    width:100%;\n  }\n  .pill{\n    width:100%;\n    padding:9px 4px;\n    font-size:12px;\n    text-align:center;\n  }\n\n  .custom{\n    min-height:0;\n    padding:15px;\n    border-radius:13px;\n  }\n  .custom h3{font-size:16px}\n  .custom p{font-size:12.5px;margin-bottom:8px}\n  .signatureGrid{grid-template-columns:repeat(2,minmax(0,1fr));gap:8px}\n  .signatureCard{padding:9px;gap:7px}\n  .signatureCard img{width:100%;height:auto;aspect-ratio:1.15\/1}\n  .signatureCard strong{font-size:12px}\n  .signatureCard p{font-size:10px;line-height:1.3}\n\n  .option,.checkRow{\n    padding:14px;\n    border-radius:12px;\n  }\n  .option input,.checkRow input{\n    flex:0 0 19px;\n    margin-top:2px;\n  }\n\n  .review{border-radius:13px}\n  .reviewSec{padding:15px}\n  .rline{\n    gap:12px;\n    font-size:12.5px;\n    align-items:flex-start;\n  }\n  .rline span:first-child{flex:0 0 42%}\n  .rline b{\n    min-width:0;\n    overflow-wrap:anywhere;\n  }\n\n  .termsSummary{\n    padding:16px;\n    border-radius:12px;\n    margin-top:18px;\n  }\n  .termsSummary ul{padding-left:18px}\n  .termsSummary li{font-size:12.5px;line-height:1.5}\n  .termsLink{font-size:13px}\n\n  .nav{\n    gap:9px;\n    padding-top:18px;\n    margin-top:24px;\n  }\n  .nav .btn{\n    flex:1 1 0;\n    min-width:0;\n    padding:12px 10px;\n    font-size:13px;\n  }\n  .nav>span:only-child{display:none}\n\n  .mobileBar{\n    display:flex;\n    left:10px;\n    right:10px;\n    bottom:max(10px,env(safe-area-inset-bottom));\n    border-radius:15px;\n    padding:9px 9px 9px 13px;\n    gap:10px;\n  }\n  .mobileBar>div{min-width:0}\n  .mobileBar small{font-size:8.5px}\n  .mobileBar b{\n    display:block;\n    font-size:18px;\n    white-space:nowrap;\n  }\n  .mobileBar .btn{\n    flex:0 0 auto;\n    min-width:118px;\n    min-height:44px;\n    font-size:12.5px;\n    padding:10px 13px;\n  }\n\n  \/* Mobile calendar behaves like a bottom sheet, not a floating desktop popover *\/\n  .calendar{\n    position:fixed!important;\n    z-index:10000;\n    left:0!important;\n    right:0!important;\n    bottom:0!important;\n    top:auto!important;\n    transform:none!important;\n    width:100%!important;\n    max-width:none!important;\n    max-height:78dvh;\n    overflow:auto;\n    border-radius:20px 20px 0 0;\n    padding:16px 14px calc(18px + env(safe-area-inset-bottom));\n    box-shadow:0 -12px 36px rgba(31,43,29,.22);\n  }\n  .calendar.open:before{\n    content:\"\";\n    display:block;\n    width:44px;\n    height:4px;\n    border-radius:999px;\n    background:#D7DDD3;\n    margin:-3px auto 12px;\n  }\n  .calHead{margin-bottom:10px}\n  .calHead strong{font-size:16px}\n  .calNav{width:40px;height:40px}\n  .week span{font-size:10px}\n  .day{\n    min-height:42px;\n    aspect-ratio:auto;\n    font-size:13px;\n  }\n\n  .modal{\n    padding:0;\n    align-items:flex-end;\n  }\n  .modalCard{\n    width:100%;\n    max-height:90dvh;\n    border-radius:20px 20px 0 0;\n  }\n  .modalHead{\n    padding:17px 16px;\n  }\n  .modalHead h3{font-size:18px}\n  .modalBody{padding:17px 16px calc(24px + env(safe-area-inset-bottom))}\n  .modalBody p,.modalBody li{font-size:13px;line-height:1.55}\n}\n@media(max-width:420px){\n  .main{padding-left:13px;padding-right:13px}\n  .cards{grid-template-columns:1fr 1fr!important}\n  .pick{padding:12px 10px}\n  .pick strong{font-size:12.5px}\n  .pill{font-size:11.5px}\n  h2{font-size:28px}\n}\n@media(max-width:340px){\n  .cards{grid-template-columns:1fr!important}\n  .pills{grid-template-columns:repeat(3,1fr)}\n  .mobileBar .btn{min-width:105px}\n}\n\n\n@media(max-width:1000px){\n  .timePicker{position:fixed!important;z-index:10000;left:0!important;right:0!important;bottom:0!important;top:auto!important;width:100%!important;max-width:none!important;max-height:72dvh;overflow:auto;border-radius:20px 20px 0 0;padding:16px 14px calc(18px + env(safe-area-inset-bottom));box-shadow:0 -12px 36px rgba(31,43,29,.22)}\n  .timePicker.open:before{content:\"\";display:block;width:44px;height:4px;border-radius:999px;background:#D7DDD3;margin:-3px auto 12px}\n  .timeGrid{grid-template-columns:repeat(2,minmax(0,1fr));gap:8px}\n  .timeSlot{min-height:58px}\n}\n\n\n\/* Unified drinks and dessert product grids *\/\n.signatureGrid,.dessertGrid{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:10px}\n.signatureCard img,.dessertCard img{width:100%;aspect-ratio:1\/1;object-fit:cover;border-radius:9px}\n.dessertWrap{margin-top:28px}.dessertGrid{margin-top:13px}\n.dessertCard{border:1px solid var(--line);border-radius:13px;padding:9px;min-width:0;background:#fff}\n.dessertCard strong{display:block;font-size:12.5px;line-height:1.3;margin:8px 0 5px}\n.dessertCard .dessertPrice{font-size:12px;font-weight:900;color:var(--green-dark)}\n.dessertCard .dessertMin{color:var(--muted);font-size:10px;margin:5px 0 9px}\n.dessertQty{display:flex;gap:4px;align-items:center;justify-content:space-between}\n.dessertQty button{border:1px solid var(--line);border-radius:7px;background:var(--green-pale);color:var(--green-dark);width:29px;height:29px;min-width:0;padding:0;font-weight:900}\n.dessertQty span{font-size:12px;font-weight:800}\n.dessertCard.active{border-color:var(--green-dark);background:var(--green-pale)}\n@media(max-width:700px){.signatureGrid,.dessertGrid{grid-template-columns:repeat(3,minmax(0,1fr))!important;gap:7px}.signatureCard{padding:6px}.signatureCard strong,.dessertCard strong{font-size:11px}.signatureCard p{display:none}.signatureCard .sigState{font-size:7px}.dessertCard{padding:6px}.dessertQty button{width:25px;height:27px}.dessertQty span{font-size:11px}}\n\n\/* Final polish: equal-height cards and aligned quantity buttons *\/\n.signatureGrid,.dessertGrid{align-items:stretch}\n.signatureCard{height:100%;justify-content:flex-start}\n.signatureCard>span{display:block}\n.signatureCard strong{margin:0;overflow-wrap:break-word}\n.signatureCard:disabled{opacity:.72}\n.dessertCard{display:flex;flex-direction:column;height:100%;gap:0}\n.dessertCard img{flex:none;display:block}\n.dessertCard strong{min-height:2.6em;overflow-wrap:break-word}\n.dessertCard .dessertPrice{line-height:1.4;min-height:1.4em}\n.dessertCard .dessertMin{line-height:1.4;margin-bottom:12px}\n.dessertQty{margin-top:auto;padding-top:5px;width:100%;min-height:39px}\n.dessertQty button{flex:0 0 30px;height:30px;display:grid;place-items:center;line-height:1}\n.dessertQty span{flex:1;text-align:center;font-variant-numeric:tabular-nums}\n@media(max-width:700px){\n .signatureCard{gap:6px}\n .signatureCard img,.dessertCard img{aspect-ratio:1\/1}\n .dessertCard strong{min-height:3.9em;line-height:1.3;margin:7px 0 4px}\n .dessertCard .dessertMin{font-size:9px;margin-bottom:8px}\n .dessertCard .dessertPrice{font-size:10.5px}\n .dessertQty{min-height:34px}\n .dessertQty button{flex-basis:26px;height:27px}\n}\n\n\/* Price stays hidden until cup selection; payment details only on final step. *\/\n#ccApp.pricePending .side .priceBox,\n#ccApp.pricePending .side .total {display:none}\n#ccApp [hidden]{display:none!important}\n#ccApp.pricePending #mTotal,#ccApp.pricePending #barTotal{display:none}\n<\/style>\n<\/head>\n<body>\n<div class=\"app\" id=\"ccApp\">\n<div class=\"shell\">\n<main class=\"main\">\n  <div class=\"top\">\n    <div><\/div>\n    <div class=\"secure\">Secure WooCommerce checkout<\/div>\n  <\/div>\n\n  <div class=\"mobileSummary\"><div class=\"row\"><div><small>Full booking total<\/small><br><b id=\"mTotal\"><\/b><\/div><div style=\"text-align:right\"><small id=\"mDetail\">Select booking<\/small><\/div><\/div><\/div>\n\n  <div class=\"steps\">\n    <div class=\"step active\" data-step=\"1\"><i>1<\/i> EVENT<\/div><div class=\"line\"><\/div>\n    <div class=\"step\" data-step=\"2\"><i>2<\/i> ORDER<\/div><div class=\"line\"><\/div>\n    <div class=\"step\" data-step=\"3\"><i>3<\/i> REVIEW<\/div><div class=\"line\"><\/div>\n    <div class=\"step\" data-step=\"4\"><i>4<\/i> PAY<\/div>\n  <\/div>\n\n  <div class=\"slotTimer\" id=\"slotTimer\"><span>Your date & time are held for checkout.<\/span><b id=\"countdown\">05:00<\/b><\/div>\n\n  <section class=\"panel active\" data-panel=\"1\">\n    <p class=\"eyebrow\">Step 01 \u2014 Event details<\/p><h2>When and where?<\/h2>\n    <p class=\"lead\">Bookings can be made from 7 days ahead. Each booking includes 5 hours on-site. We accept one catering booking per day. Choose an available date, then select your preferred start time.<\/p>\n\n    <div class=\"grid2\">\n      <div class=\"field\">\n        <label class=\"label\">Event date<\/label>\n        <div class=\"dateWrap\">\n          <button type=\"button\" class=\"dateDisplay placeholder\" id=\"dateDisplay\"><span id=\"dateText\">Select event date<\/span><span>\u25a3<\/span><\/button>\n          <input type=\"hidden\" id=\"eventDate\">\n          <div class=\"calendar\" id=\"calendar\">\n            <div class=\"calHead\"><button type=\"button\" class=\"calNav\" id=\"prevMonth\">\u2039<\/button><strong id=\"calTitle\"><\/strong><button type=\"button\" class=\"calNav\" id=\"nextMonth\">\u203a<\/button><\/div>\n            <div class=\"week\"><span>Su<\/span><span>Mo<\/span><span>Tu<\/span><span>We<\/span><span>Th<\/span><span>Fr<\/span><span>Sa<\/span><\/div>\n            <div class=\"days\" id=\"calDays\"><\/div>\n          <\/div>\n        <\/div>\n      <\/div>\n      <div class=\"field\">\n        <label class=\"label\">Start time<\/label>\n        <div class=\"timeWrap\">\n          <button type=\"button\" class=\"timeDisplay placeholder\" id=\"timeDisplay\"><span id=\"timeText\">Select start time<\/span><span class=\"timeIcon\">\u25f7<\/span><\/button>\n          <select id=\"eventTime\" aria-hidden=\"true\" tabindex=\"-1\" style=\"display:none\"><option value=\"\">Select start time<\/option><\/select>\n          <div class=\"timePicker\" id=\"timePicker\">\n            <div class=\"timePickerHead\"><strong>Choose start time<\/strong><button type=\"button\" class=\"timeClose\" id=\"timeClose\">\u00d7<\/button><\/div>\n            <div class=\"timeGrid\" id=\"timeGrid\"><\/div>\n            <div class=\"timeHint\">Each booking reserves a 5-hour service window.<\/div>\n          <\/div>\n        <\/div>\n      <\/div>\n    <\/div>\n\n    <div class=\"field\"><label class=\"label\">Emirate \/ transport<\/label>\n      <div class=\"cards\" id=\"emirates\">\n        <button type=\"button\" class=\"pick\" data-key=\"sharjah\" data-name=\"Sharjah\" data-price=\"600\"><div class=\"price\">600 AED transport<\/div><strong>Sharjah<\/strong><\/button>\n        <button type=\"button\" class=\"pick\" data-key=\"ajman\" data-name=\"Ajman\" data-price=\"700\"><div class=\"price\">700 AED transport<\/div><strong>Ajman<\/strong><\/button>\n        <button type=\"button\" class=\"pick\" data-key=\"dubai\" data-name=\"Dubai\" data-price=\"500\"><div class=\"price\">500 AED transport<\/div><strong>Dubai<\/strong><\/button>\n        <button type=\"button\" class=\"pick\" data-key=\"uaq\" data-name=\"Umm Al Quwain\" data-price=\"900\"><div class=\"price\">900 AED transport<\/div><strong>Umm Al Quwain<\/strong><\/button>\n        <button type=\"button\" class=\"pick\" data-key=\"rak\" data-name=\"Ras Al Khaimah\" data-price=\"1000\"><div class=\"price\">1,000 AED transport<\/div><strong>Ras Al Khaimah<\/strong><\/button>\n        <button type=\"button\" class=\"pick\" data-key=\"fujairah\" data-name=\"Fujairah \/ Khor Fakkan \/ Kalba\" data-price=\"1000\"><div class=\"price\">1,000 AED transport<\/div><strong>Fujairah \/ Khor Fakkan<\/strong><\/button>\n        <button type=\"button\" class=\"pick\" data-key=\"abudhabi\" data-name=\"Abu Dhabi \/ Al Ain \/ Hatta\" data-price=\"1200\"><div class=\"price\">1,200 AED transport<\/div><strong>Abu Dhabi \/ Al Ain \/ Hatta<\/strong><\/button>\n      <\/div>\n    <\/div>\n    <div class=\"field\"><label class=\"label\">Venue \/ location<\/label><textarea id=\"venue\" placeholder=\"Venue name, address, or Google Maps pin\"><\/textarea><\/div>\n    <div class=\"error\" id=\"err1\"><\/div>\n    <div class=\"nav\"><span><\/span><button type=\"button\" class=\"btn primary next\">Continue \u2192<\/button><\/div>\n  <\/section>\n\n  <section class=\"panel\" data-panel=\"2\">\n    <p class=\"eyebrow\">Step 02 \u2014 Order<\/p><h2>Cups & quantity.<\/h2>\n    <p class=\"lead\">Choose your cup type and quantity. Select a cup type to start building your booking total.<\/p>\n    <div class=\"field\"><label class=\"label\">Cup type<\/label>\n      <div class=\"cupGrid\">\n        <button type=\"button\" class=\"cup\" data-cup=\"mini\"><h3>Mini cups <span class=\"badge\">Up to 8 oz<\/span><\/h3><p>Each drink is served in a cup up to 8 oz. Drinks normally served in smaller cups keep their usual size.<\/p><div class=\"tier\">Minimum 60 cups<br>60\u2013140: 25 AED \/ cup<br>145+: 21 AED \/ cup<\/div><\/button>\n        <button type=\"button\" class=\"cup\" data-cup=\"regular\"><h3>Regular cups <span class=\"badge\">Usual sizes<\/span><\/h3><p>Each drink is served in its usual cup size. Cup size varies by drink.<\/p><div class=\"tier\">Minimum 30 cups<br>30\u201370: 30 AED \/ cup<br>75+: 27 AED \/ cup<\/div><\/button>\n      <\/div>\n    <\/div>\n    <div class=\"field\"><label class=\"label\">Quantity<\/label>\n      <div class=\"qtyRow\"><div class=\"qty\"><button type=\"button\" id=\"minus\">\u2212<\/button><input id=\"qty\" type=\"number\" value=\"\" placeholder=\"0\" min=\"1\"><button type=\"button\" id=\"plus\">+<\/button><\/div>\n      <div class=\"pills\"><button class=\"pill\" type=\"button\" data-q=\"60\">60<\/button><button class=\"pill\" type=\"button\" data-q=\"100\">100<\/button><button class=\"pill\" type=\"button\" data-q=\"145\">145<\/button><button class=\"pill\" type=\"button\" data-q=\"200\">200<\/button><button class=\"pill\" type=\"button\" data-q=\"300\">300<\/button><\/div><\/div>\n      <div class=\"qtyPriceInfo\" id=\"qtyPriceInfo\">Select a cup type to see pricing.<\/div>\n      <div class=\"error\" id=\"err2\"><\/div>\n    <\/div>\n    <div class=\"field\"><label class=\"label\">Cup customization<\/label>\n      <div class=\"customGrid\">\n        <button type=\"button\" class=\"custom selected\" data-custom=\"standard\" data-price=\"0\"><h3>Standard cups<\/h3><p>Original cup design with no extra customization.<\/p><div class=\"cost\">Free<\/div><\/button>\n        <button type=\"button\" class=\"custom\" data-custom=\"logo\" data-price=\"300\"><h3>Event logo cups<\/h3><p>Add your event, wedding or company logo.<\/p><div class=\"cost\">+300 AED<\/div><\/button>\n        <button type=\"button\" class=\"custom\" data-custom=\"full\" data-price=\"350\"><h3>Fully custom cups<\/h3><p>Custom colors, logo and complete cup direction.<\/p><div class=\"cost\">+350 AED<\/div><\/button>\n      <\/div>\n      <label class=\"option\"><input type=\"checkbox\" id=\"femaleBarista\"><span><strong>Female barista<\/strong><small>For ladies-only events.<\/small><\/span><\/label>\n    <\/div>\n\n    <div class=\"signatureWrap\">\n      <label class=\"label\">Drinks <span class=\"optionalTag\">(optional)<\/span><\/label>\n      <p class=\"signatureIntro\">Choose up to 3 ChaCha Signatures (optional). Included at no extra charge.<\/p>\n      <div class=\"signatureNotice\">All regular hot &amp; iced coffee classics are included in every order \u2014 no selection needed.<\/div>\n      <div id=\"signatureGroups\"><div class=\"signatureEmpty\">Loading drinks from WooCommerce\u2026<\/div><\/div>\n      <div class=\"signatureCount\" id=\"signatureCount\">0 of 3 selected<\/div>\n    <\/div>\n    <div class=\"dessertWrap\">\n      <label class=\"label\">Desserts <span class=\"optionalTag\">(optional extra)<\/span><\/label>\n      <p class=\"signatureIntro\">Add desserts to your catering booking. Minimum quantities apply.<\/p>\n      <div id=\"dessertProducts\" class=\"dessertGrid\"><div class=\"signatureEmpty\">Loading desserts\u2026<\/div><\/div>\n    <\/div>\n\n    <div class=\"nav\"><button type=\"button\" class=\"btn secondary back\">\u2190 Back<\/button><button type=\"button\" class=\"btn primary next\">Review \u2192<\/button><\/div>\n  <\/section>\n\n  <section class=\"panel\" data-panel=\"3\">\n    <p class=\"eyebrow\">Step 03 \u2014 Review<\/p><h2>Your details.<\/h2>\n    <p class=\"lead\">Review the booking and enter your contact information.<\/p>\n    <div class=\"review\" id=\"review\"><\/div>\n    <div style=\"height:22px\"><\/div>\n    <div class=\"grid2\">\n      <div class=\"field\"><label class=\"label\">Full name<\/label><input id=\"name\" type=\"text\" placeholder=\"Your name\" autocomplete=\"name\"><\/div>\n      <div class=\"field\"><label class=\"label\">Mobile number<\/label><input id=\"phone\" type=\"tel\" placeholder=\"+971 50 123 4567\" autocomplete=\"tel\"><\/div>\n    <\/div>\n    <div class=\"field\"><label class=\"label\">Email (optional)<\/label><input id=\"email\" type=\"email\" placeholder=\"you@example.com\" autocomplete=\"email\"><\/div>\n\n    <div class=\"termsSummary\">\n      <h3>TERMS SUMMARY<\/h3>\n      <ul>\n        <li>Prices are exclusive of VAT \u2014 5% VAT is added to the total.<\/li>\n        <li>Pay either the 1,500 AED deposit or the full booking amount at checkout to confirm and reserve your date.<\/li>\n        <li>Service includes 5 hours on-site. Extra hours: 150 AED each.<\/li>\n        <li>Payments are non-refundable unless cancelled at least 3 weeks prior.<\/li>\n        <li>Date \/ time \/ location \/ order changes require at least 1 week notice and are subject to availability.<\/li>\n      <\/ul>\n      <button type=\"button\" class=\"termsLink\" id=\"openTerms\">Read full Terms & Conditions \u2192<\/button>\n    <\/div>\n\n    <label class=\"checkRow\"><input type=\"checkbox\" id=\"terms\"><span><strong>I have read and agree to the full Terms & Conditions<\/strong><\/span><\/label>\n    <label class=\"checkRow\"><input type=\"checkbox\" id=\"contactConsent\"><span><strong>I'd also like to be contacted about this enquiry by phone, WhatsApp, or SMS<\/strong><br><small style=\"color:var(--muted)\">Optional<\/small><\/span><\/label>\n\n    <div class=\"error\" id=\"err3\"><\/div>\n    <div class=\"nav\"><button type=\"button\" class=\"btn secondary back\">\u2190 Back<\/button><button type=\"button\" class=\"btn primary next\">Continue to payment \u2192<\/button><\/div>\n  <\/section>\n\n  <section class=\"panel\" data-panel=\"4\">\n    <p class=\"eyebrow\">Step 04 \u2014 Secure payment<\/p><h2>Pay your booking.<\/h2>\n\n    <div class=\"payHero\">\n      <div class=\"payHeroTop\">\n        <div><div class=\"miniLabel\" id=\"payHeroLabel\">Paying today<\/div><div class=\"heroSub\" id=\"payHeroSub\">Confirms your booking<\/div><\/div>\n        <div class=\"heroAmount\"><span id=\"payHeroAmount\">1,500<\/span> <small>AED<\/small><\/div>\n      <\/div>\n      <div class=\"payHeroRemain\"><span>Remaining to pay on event day<\/span><strong id=\"payHeroRemaining\">0 AED<\/strong><\/div>\n    <\/div>\n\n    <label class=\"label\">Payment option<\/label>\n    <label class=\"payChoice selected\" data-pay-choice=\"deposit\">\n      <input type=\"radio\" name=\"paymentChoice\" value=\"deposit\" checked>\n      <span class=\"payCopy\"><strong>Pay deposit only \u2014 1,500 AED<\/strong><small id=\"depositChoiceText\">Pay 1,500 AED to confirm your booking. The remaining balance will be due on the event day.<\/small><\/span>\n      <span class=\"choiceAmount\">1,500 AED<\/span>\n    <\/label>\n    <label class=\"payChoice\" data-pay-choice=\"full\">\n      <input type=\"radio\" name=\"paymentChoice\" value=\"full\">\n      <span class=\"payCopy\"><strong>Pay full amount now<\/strong><small>Settle everything now. No payment needed on the event day.<\/small><\/span>\n      <span class=\"choiceAmount\" id=\"fullChoiceAmount\">0 AED<\/span>\n    <\/label>\n\n    <div class=\"securePayBox\"><strong>Secure WooCommerce checkout<\/strong>You\u2019ll continue to your normal checkout page, where your name, phone and email remain prefilled and you can choose the available payment method.<\/div>\n\n    <div class=\"error\" id=\"err5\"><\/div>\n    <div id=\"loader\" style=\"display:none;color:var(--muted);font-size:13px;margin-top:12px\">Preparing secure checkout\u2026<\/div>\n    <div class=\"nav\"><button type=\"button\" class=\"btn secondary back\">\u2190 Back<\/button><button type=\"button\" class=\"btn primary\" id=\"pay\">Pay 1,500 AED \u2192<\/button><\/div>\n  <\/section>\n<\/main>\n\n<aside class=\"side\">\n  <div class=\"summary\">\n    <h3>Live summary<\/h3><div class=\"sub\">Updates in real time<\/div>\n    <div class=\"sumrow\"><span>Date<\/span><span id=\"sDate\">\u2014<\/span><\/div>\n    <div class=\"sumrow\"><span>Time<\/span><span id=\"sTime\">\u2014<\/span><\/div>\n    <div class=\"sumrow\"><span>Emirate<\/span><span id=\"sEmirate\">\u2014<\/span><\/div>\n    <div class=\"sumrow\"><span>Cup type<\/span><span id=\"sCup\">\u2014<\/span><\/div>\n    <div class=\"sumrow\"><span>Quantity<\/span><span id=\"sQty\">\u2014<\/span><\/div>\n    <div class=\"sumrow\"><span>Cup option<\/span><span id=\"sCustom\">Standard cups<\/span><\/div>\n    <div class=\"sumrow\"><span>Drinks<\/span><span id=\"sSignatures\">None selected<\/span><\/div>\n    <div class=\"sumrow\"><span>Desserts<\/span><span id=\"sDesserts\">None selected<\/span><\/div>\n    <div class=\"priceBox\">\n      <div class=\"rline\"><span>Cups<\/span><b id=\"pCups\">0 AED<\/b><\/div>\n      <div class=\"rline\"><span>Transport<\/span><b id=\"pTransport\">0 AED<\/b><\/div>\n      <div class=\"rline\"><span>Customization<\/span><b id=\"pCustom\">0 AED<\/b><\/div>\n      <div class=\"rline\"><span>Desserts<\/span><b id=\"pDesserts\">0 AED<\/b><\/div>\n      <div class=\"rline\"><span>Subtotal excl. VAT<\/span><b id=\"pSubtotal\">0 AED<\/b><\/div>\n      <div class=\"rline\"><span>VAT included (5%)<\/span><b id=\"pVat\">0 AED<\/b><\/div>\n    <\/div>\n    <div class=\"total\"><small>Total (VAT included)<\/small><b id=\"sTotal\">0 AED<\/b><\/div>\n    <div class=\"depositBox\" id=\"sidePaymentChoices\">\n      <div class=\"depositRow payNow\"><span id=\"sPayLabel\">Deposit today<\/span><b id=\"sDeposit\">1,500 AED<\/b><\/div>\n      <div class=\"depositRow\"><span>Remaining due on event day<\/span><b id=\"sRemaining\">0 AED<\/b><\/div>\n    <\/div>\n    <div class=\"note\" id=\"paymentNote\">Pay 1,500 AED today to confirm the booking. The remaining balance is payable on the event day.<\/div>\n  <\/div>\n<\/aside>\n<\/div>\n\n<div class=\"mobileBar\"><div><small id=\"barPriceLabel\">Select cups to see total<\/small><b id=\"barTotal\"><\/b><\/div><button type=\"button\" class=\"btn\" id=\"mobileAction\">Continue \u2192<\/button><\/div>\n<\/div>\n\n<div class=\"modal\" id=\"termsModal\" role=\"dialog\" aria-modal=\"true\">\n  <div class=\"modalCard\">\n    <div class=\"modalHead\"><h3>Terms & Conditions<\/h3><button type=\"button\" class=\"close\" id=\"closeTerms\">\u00d7<\/button><\/div>\n    <div class=\"modalBody\">\n      <p>Please read these terms carefully. By confirming a catering booking with us, you agree to all the points below.<\/p>\n      <ol>\n        <li><strong>VAT.<\/strong> All prices listed are exclusive of VAT. VAT will be added to the final total.<\/li>\n        <li><strong>Booking confirmation.<\/strong> A booking is confirmed after either the 1,500 AED deposit or the full booking amount has been successfully paid.<\/li>\n        <li><strong>Deposit payment.<\/strong> You may pay the fixed 1,500 AED deposit or the full booking amount at checkout. If you choose the deposit, the remaining balance shown in the booking summary is payable on the event day.<\/li>\n        <li><strong>Payment receipt.<\/strong> Once checkout payment is completed, the WooCommerce order and payment confirmation will be used as the booking record. If a deposit was selected, the outstanding balance remains due on the event day.<\/li>\n        <li><strong>Service duration.<\/strong> The catering service is provided for 5 hours only. Any additional hour will be charged at 150 AED per hour.<\/li>\n        <li><strong>Refund policy.<\/strong> Payment is non-refundable unless the event is cancelled at least 3 weeks before the event date.<\/li>\n        <li><strong>Approved refunds.<\/strong> In some cases, events may be cancelled due to unexpected circumstances. If the cancellation is approved for a refund, the refunded amount will be processed within 5\u20137 working days.<\/li>\n        <li><strong>Extra consumption.<\/strong> If additional cups or items are consumed beyond the confirmed order, the extra amount must be paid on the same day after the event.<\/li>\n        <li><strong>Changes & rescheduling.<\/strong> Any changes to the event date, time, location, or order details must be communicated at least one week in advance and are subject to availability.<\/li>\n        <li><strong>Delays.<\/strong> We are not responsible for delays caused by incorrect location details, access restrictions, or last-minute changes from the client's side.<\/li>\n        <li><strong>Final confirmation.<\/strong> Final confirmation of the booking means the client agrees to all the terms and conditions listed above.<\/li>\n      <\/ol>\n    <\/div>\n  <\/div>\n<\/div>\n\n<script>\n(function(){\n\"use strict\";\nconst root=document.getElementById(\"ccApp\"),$=s=>root.querySelector(s),$$=s=>Array.from(root.querySelectorAll(s));\nlet step=1,countdownHandle=null;\nconst state={date:\"\",holdToken:\"\",holdExpires:0,emirateKey:\"\",emirateName:\"\",transport:0,cup:\"\",qty:0,custom:\"standard\",customPrice:0,signatures:[],signatureProducts:[],dessertProducts:[],desserts:{},paymentChoice:\"deposit\"};\n\ntry{state.holdToken=localStorage.getItem(\"cc_hold_token\")||\"\"}catch(e){}\nfunction token(){if(!state.holdToken){state.holdToken=(crypto.randomUUID?crypto.randomUUID():\"cc-\"+Date.now()+\"-\"+Math.random().toString(36).slice(2));try{localStorage.setItem(\"cc_hold_token\",state.holdToken)}catch(e){}}return state.holdToken}\nconst moneyFormat=new Intl.NumberFormat(\"en-AE\",{minimumFractionDigits:2,maximumFractionDigits:2});\nfunction money(n){return moneyFormat.format(Math.round((Number(n)+Number.EPSILON)*100)\/100)+\" AED\"}\nfunction esc(v){return String(v||\"\").replace(\/[&<>\"']\/g,c=>({\"&\":\"&amp;\",\"<\":\"&lt;\",\">\":\"&gt;\",'\"':\"&quot;\",\"'\":\"&#039;\"}[c]))}\nfunction unitPrice(){if(state.cup===\"mini\")return state.qty>=145?21:25;if(state.cup===\"regular\")return state.qty>=75?27:30;return 0}\nfunction dessertTotal(){return state.dessertProducts.reduce((sum,p)=>sum+(state.desserts[p.id]||0)*p.price,0)}\nfunction selectedDessertNames(){return state.dessertProducts.filter(p=>state.desserts[p.id]).map(p=>`${p.name} \u00d7 ${state.desserts[p.id]}`)}\nfunction subtotal(){return !state.cup||!state.qty?0:unitPrice()*state.qty+state.transport+state.customPrice+dessertTotal()}\nfunction total(){return subtotal()} \/\/ All listed prices already INCLUDE 5% VAT\nfunction vat(){return Math.round((total()-total()\/1.05)*100)\/100}\nfunction netSubtotal(){return Math.round((total()-vat())*100)\/100}\nfunction deposit(){return 1500}\nfunction remaining(){return Math.max(0,total()-deposit())}\nfunction timeLabel(v){if(!v)return \"\u2014\";let [h,m]=v.split(\":\").map(Number),ap=h>=12?\"PM\":\"AM\",hr=h%12||12;return hr+\":\"+String(m).padStart(2,\"0\")+\" \"+ap}\nfunction formatDate(iso){if(!iso)return \"\u2014\";let [y,m,d]=iso.split(\"-\").map(Number);return new Date(y,m-1,d).toLocaleDateString(\"en-AE\",{weekday:\"short\",day:\"numeric\",month:\"short\",year:\"numeric\"})}\n\/\/ Read-only catalogue responses can be reused briefly; booking availability is NEVER cached.\nconst catalogueActions=new Set([\"cc_get_signature_products\",\"cc_get_catering_desserts\"]);\nconst cataloguePending=new Map();\nasync function api(data){\n const action=data.action;\n const isCatalogue=catalogueActions.has(action);\n const cacheKey=\"cc_catalogue_v1_\"+action;\n if(isCatalogue){\n  try{\n   const saved=sessionStorage.getItem(cacheKey);\n   if(saved){const entry=JSON.parse(saved);if(Date.now()-entry.saved<120000&&entry.data?.success)return entry.data;}\n  }catch(e){}\n  if(cataloguePending.has(action))return cataloguePending.get(action);\n }\n const request=(async()=>{\n  const body=new URLSearchParams(data);\n  const r=await fetch(\"\/wp-admin\/admin-ajax.php\",{method:\"POST\",headers:{\"Content-Type\":\"application\/x-www-form-urlencoded; charset=UTF-8\"},body:body.toString(),credentials:\"same-origin\"});\n  const response=await r.json();\n  if(isCatalogue&&response.success){try{sessionStorage.setItem(cacheKey,JSON.stringify({saved:Date.now(),data:response}));}catch(e){}}\n  return response;\n })();\n if(isCatalogue){cataloguePending.set(action,request);try{return await request}finally{cataloguePending.delete(action)}}\n return request;\n}\n\nfunction selectedSignatureNames(){return state.signatures.map(id=>{let p=state.signatureProducts.find(x=>String(x.id)===String(id));return p?p.name:\"\"}).filter(Boolean)}\nfunction payNow(){return state.paymentChoice===\"full\"?total():deposit()}\nfunction dueLater(){return state.paymentChoice===\"full\"?0:remaining()}\nfunction updateQtyPriceInfo(){\n const box=$(\"#qtyPriceInfo\");\n if(!box)return;\n if(!state.cup){box.textContent=\"Choose a cup type to start your total.\";return;}\n const q=state.qty;\n\n if(state.cup===\"mini\"){\n   if(q<60){\n     const more=60-q;\n     box.innerHTML=`<strong>Minimum 60 cups.<\/strong> Add <strong>${more} more ${more===1?\"cup\":\"cups\"}<\/strong> to continue.`;\n     return;\n   }\n   if(q<145){\n     const more=145-q;\n     box.innerHTML=`<strong>25 AED \/ cup.<\/strong> Add <strong>${more} more ${more===1?\"cup\":\"cups\"}<\/strong> to get the lower price of <strong>21 AED \/ cup.<\/strong>`;\n     return;\n   }\n   box.innerHTML=`<strong>21 AED \/ cup.<\/strong> Lower price unlocked. You save <strong>4 AED per cup (${money(q*4)} total)<\/strong> compared with the 25 AED rate.`;\n   return;\n }\n\n if(state.cup===\"regular\"){\n   if(q<30){\n     const more=30-q;\n     box.innerHTML=`<strong>Minimum 30 cups.<\/strong> Add <strong>${more} more ${more===1?\"cup\":\"cups\"}<\/strong> to continue.`;\n     return;\n   }\n   if(q<=70){\n     const more=75-q;\n     box.innerHTML=`<strong>30 AED \/ cup.<\/strong> Add <strong>${more} more ${more===1?\"cup\":\"cups\"}<\/strong> to get the lower price of <strong>27 AED \/ cup.<\/strong>`;\n     return;\n   }\n   if(q>=71&&q<=74){\n     const more=75-q;\n     box.innerHTML=`Add <strong>${more} more ${more===1?\"cup\":\"cups\"}<\/strong> to get the lower price of <strong>27 AED \/ cup.<\/strong>`;\n     return;\n   }\n   box.innerHTML=`<strong>27 AED \/ cup.<\/strong> Lower price unlocked. You save <strong>3 AED per cup (${money(q*3)} total)<\/strong> compared with the 30 AED rate.`;\n   return;\n }\n\n box.textContent=\"Select a cup type to see quantity pricing.\";\n}\nfunction updatePaymentUI(){\n let full=total(),pay=payNow(),due=dueLater();\n let a=$(\"#payHeroAmount\");if(a)a.textContent=new Intl.NumberFormat(\"en-AE\",{minimumFractionDigits:pay%1?2:0,maximumFractionDigits:2}).format(pay);\n if($(\"#payHeroRemaining\"))$(\"#payHeroRemaining\").textContent=money(due);\n if($(\"#fullChoiceAmount\"))$(\"#fullChoiceAmount\").textContent=money(full);\n if($(\"#depositChoiceText\"))$(\"#depositChoiceText\").textContent=`Pay 1,500 AED to confirm your booking. ${money(Math.max(0,full-1500))} will be due on the event day.`;\n if($(\"#pay\"))$(\"#pay\").textContent=`Pay ${money(pay)} \u2192`;\n $$(\".payChoice\").forEach(x=>x.classList.toggle(\"selected\",x.dataset.payChoice===state.paymentChoice));\n if($(\"#sPayLabel\"))$(\"#sPayLabel\").textContent=state.paymentChoice===\"full\"?\"Pay today\":\"Deposit today\";\n if($(\"#paymentNote\"))$(\"#paymentNote\").textContent=state.paymentChoice===\"full\"?\"Full booking amount selected. Nothing will remain due on the event day.\":\"Pay 1,500 AED today to confirm the booking. The remaining balance is payable on the event day.\";\n}\nfunction update(){\n state.qty=Math.max(0,parseInt($(\"#qty\").value||0,10)||0);\n $(\"#sDate\").textContent=formatDate(state.date);$(\"#sTime\").textContent=timeLabel($(\"#eventTime\").value);\n $(\"#sEmirate\").textContent=state.emirateName?state.emirateName+\" \u00b7 \"+money(state.transport):\"\u2014\";\n $(\"#sCup\").textContent=state.cup===\"mini\"?\"Small cups \u00b7 \"+money(unitPrice())+\" each\":state.cup===\"regular\"?\"Normal cups \u00b7 \"+money(unitPrice())+\" each\":\"\u2014\";\n $(\"#sQty\").textContent=state.cup&&state.qty?state.qty+\" cups\":\"\u2014\";$(\"#sCustom\").textContent=state.custom===\"standard\"?\"Standard cups\":state.custom===\"logo\"?\"Event logo cups\":\"Fully custom cups\";\n let sigs=selectedSignatureNames();if($(\"#sSignatures\"))$(\"#sSignatures\").textContent=sigs.length?sigs.join(\", \"):\"None selected\";\n if($(\"#sDesserts\"))$(\"#sDesserts\").textContent=selectedDessertNames().join(\", \")||\"None selected\";\n if($(\"#pDesserts\"))$(\"#pDesserts\").textContent=money(dessertTotal());\n $(\"#pCups\").textContent=money(unitPrice()*state.qty);$(\"#pTransport\").textContent=money(state.transport);$(\"#pCustom\").textContent=money(state.customPrice);$(\"#pSubtotal\").textContent=money(netSubtotal());$(\"#pVat\").textContent=money(vat());\n $(\"#sTotal\").textContent=state.cup&&state.qty?money(total()):\"\";$(\"#mTotal\").textContent=state.cup&&state.qty?money(total()):\"\";$(\"#barTotal\").textContent=state.cup&&state.qty?money(total()):\"\";$(\"#sDeposit\").textContent=money(payNow());$(\"#sRemaining\").textContent=money(dueLater());$(\"#mDetail\").textContent=state.cup?(state.cup===\"mini\"?\"Small\":\"Normal\")+\" \u00b7 \"+state.qty+\" cups\":\"Select booking\";\n const hasCups=Boolean(state.cup&&state.qty>0);\n root.classList.toggle(\"pricePending\",!hasCups);\n $(\"#barPriceLabel\").textContent=hasCups?\"Full booking total (incl. VAT)\":\"Select cups to see total\";\n if($(\"#sidePaymentChoices\"))$(\"#sidePaymentChoices\").hidden=step!==4;\n if($(\"#paymentNote\"))$(\"#paymentNote\").hidden=step!==4;\n updateQtyPriceInfo();updatePaymentUI();syncMobile();\n}\nfunction syncMobile(){let labels={1:\"Continue \u2192\",2:\"Review \u2192\",3:\"Payment \u2192\",4:\"Checkout \u2192\"};$(\"#mobileAction\").textContent=labels[step]||\"Continue \u2192\"}\nfunction renderStep(){$$(\".panel\").forEach(p=>p.classList.toggle(\"active\",+p.dataset.panel===step));$$(\".step\").forEach(s=>{let n=+s.dataset.step;s.classList.toggle(\"active\",n===step);s.classList.toggle(\"done\",n<step)});update();syncMobile();window.scrollTo({top:root.offsetTop,behavior:\"smooth\"})}\nfunction validate(){\n if(step===1){let missing=[];if(!state.date)missing.push(\"event date\");if(!$(\"#eventTime\").value)missing.push(\"start time\");if(!state.emirateKey)missing.push(\"emirate\");if(!$(\"#venue\").value.trim())missing.push(\"venue\");$(\"#err1\").textContent=missing.length?\"Please select: \"+missing.join(\", \")+\".\":\"\";$(\"#err1\").style.display=missing.length?\"block\":\"none\";return !missing.length}\n if(step===2){let msg=\"\";if(!state.cup)msg=\"Please select a cup type.\";else if(state.cup===\"mini\"&&state.qty<60)msg=\"Small cups require at least 60 cups.\";else if(state.cup===\"regular\"&&state.qty<30)msg=\"Normal cups require at least 30 cups.\";else if(state.cup===\"regular\"&&state.qty>=71&&state.qty<=74)msg=\"Normal cup pricing has no tier for 71\u201374 cups. Please choose 70 or 75+.\";$(\"#err2\").textContent=msg;$(\"#err2\").style.display=msg?\"block\":\"none\";return !msg}\n if(step===3){let msg=\"\";if(!$(\"#name\").value.trim())msg=\"Please enter your full name.\";else if(!$(\"#phone\").value.trim())msg=\"Please enter your mobile number.\";else if($(\"#email\").value.trim()&&!\/^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$\/.test($(\"#email\").value.trim()))msg=\"Please enter a valid email address.\";else if(!$(\"#terms\").checked)msg=\"Please read and agree to the Terms & Conditions.\";$(\"#err3\").textContent=msg;$(\"#err3\").style.display=msg?\"block\":\"none\";return !msg}\n return true\n}\nfunction review(target){let cup=state.cup===\"mini\"?\"Small cups 8 oz\":\"Normal cups 16 oz\",custom=state.custom===\"standard\"?\"Standard cups\":state.custom===\"logo\"?\"Event logo cups\":\"Fully custom cups\",sigs=selectedSignatureNames();target.innerHTML=`<div class=\"reviewSec\"><h3>EVENT<\/h3><div class=\"rline\"><span>Date<\/span><b>${esc(formatDate(state.date))}<\/b><\/div><div class=\"rline\"><span>Time<\/span><b>${esc(timeLabel($(\"#eventTime\").value))}<\/b><\/div><div class=\"rline\"><span>Location<\/span><b>${esc(state.emirateName)}<\/b><\/div><div class=\"rline\"><span>Venue<\/span><b>${esc($(\"#venue\").value)}<\/b><\/div><\/div><div class=\"reviewSec\"><h3>ORDER<\/h3><div class=\"rline\"><span>Cup type<\/span><b>${cup}<\/b><\/div><div class=\"rline\"><span>Quantity<\/span><b>${state.qty} cups<\/b><\/div><div class=\"rline\"><span>Unit price<\/span><b>${money(unitPrice())}<\/b><\/div><div class=\"rline\"><span>Customization<\/span><b>${custom}<\/b><\/div><div class=\"rline\"><span>Female barista<\/span><b>${$(\"#femaleBarista\").checked?\"Yes\":\"No\"}<\/b><\/div><div class=\"rline\"><span>Drinks<\/span><b>${sigs.length?esc(sigs.join(\", \")):\"None selected\"}<\/b><\/div><div class=\"rline\"><span>Desserts<\/span><b>${esc(selectedDessertNames().join(\", \")||\"None selected\")}<\/b><\/div><\/div><div class=\"reviewSec\"><h3>PRICE<\/h3><div class=\"rline\"><span>Subtotal excl. VAT<\/span><b>${money(netSubtotal())}<\/b><\/div><div class=\"rline\"><span>VAT included (5%)<\/span><b>${money(vat())}<\/b><\/div><div class=\"rline\"><span>Total (VAT included)<\/span><b>${money(total())}<\/b><\/div><\/div>`}\n\nasync function next(){if(!validate())return;if(step===1){if(!state.holdExpires||Date.now()>=state.holdExpires){let ok=await holdSlot();if(!ok)return}}if(step===2)review($(\"#review\"));if(step===3)updatePaymentUI();if(step<4){step++;renderStep()}}\nfunction back(){if(step>1){step--;renderStep()}}\n$$(\".next\").forEach(b=>b.addEventListener(\"click\",next));$$(\".back\").forEach(b=>b.addEventListener(\"click\",back));$(\"#mobileAction\").addEventListener(\"click\",()=>step<4?next():pay());\n\n$(\"#emirates\").addEventListener(\"click\",e=>{let c=e.target.closest(\".pick\");if(!c)return;$$(\".pick\").forEach(x=>x.classList.remove(\"selected\"));c.classList.add(\"selected\");state.emirateKey=c.dataset.key;state.emirateName=c.dataset.name;state.transport=+c.dataset.price;update()});\n$$(\".cup\").forEach(c=>c.addEventListener(\"click\",()=>{$$(\".cup\").forEach(x=>x.classList.remove(\"selected\"));c.classList.add(\"selected\");state.cup=c.dataset.cup;if(state.cup===\"mini\"&&state.qty<60)$(\"#qty\").value=60;if(state.cup===\"regular\"&&state.qty<30)$(\"#qty\").value=30;update()}));\n$$(\".custom\").forEach(c=>c.addEventListener(\"click\",()=>{$$(\".custom\").forEach(x=>x.classList.remove(\"selected\"));c.classList.add(\"selected\");state.custom=c.dataset.custom;state.customPrice=+c.dataset.price;update()}));\n\nfunction renderSignatures(){\n const wrap=$(\"#signatureGroups\");if(!wrap)return;\n if(!state.signatureProducts.length){wrap.innerHTML='<div class=\"signatureEmpty\">No drinks found in WooCommerce.<\/div>';return}\n wrap.innerHTML=`<div class=\"signatureGrid\">${state.signatureProducts.map(p=>`<button type=\"button\" class=\"signatureCard\" data-signature-id=\"${p.id}\"><img loading=\"lazy\" src=\"${esc(p.image)}\" alt=\"${esc(p.name)}\" loading=\"lazy\" decoding=\"async\" width=\"220\" height=\"220\"><span><span class=\"sigState\">Tap to select<\/span><strong>${esc(p.name)}<\/strong><\/span><\/button>`).join(\"\")}<\/div>`;\n refreshSignatureStates();\n}\nfunction refreshSignatureStates(){\n const selected=new Set(state.signatures.map(String));\n $$(\".signatureCard\").forEach(card=>{\n   const active=selected.has(card.dataset.signatureId);\n   card.classList.toggle(\"selected\",active);\n   card.disabled=!active&&selected.size>=3;\n   card.querySelector(\".sigState\").textContent=active?\"Selected\":\"Tap to select\";\n });\n $(\"#signatureCount\").textContent=`${state.signatures.length} of 3 selected`;\n}\n$(\"#signatureGroups\").addEventListener(\"click\",e=>{\n const card=e.target.closest(\"button[data-signature-id]\");if(!card||card.disabled)return;\n const id=String(card.dataset.signatureId),i=state.signatures.map(String).indexOf(id);\n if(i>=0)state.signatures.splice(i,1);else if(state.signatures.length<3)state.signatures.push(id);\n refreshSignatureStates();update();\n});\nasync function loadSignatures(){try{let d=await api({action:\"cc_get_signature_products\"});if(!d.success)throw new Error(d.data?.message||\"Could not load drinks.\");state.signatureProducts=d.data.products||[];renderSignatures();update()}catch(e){$(\"#signatureGroups\").innerHTML=`<div class=\"signatureEmpty\">${esc(e.message)}<\/div>`}}\nfunction renderDesserts(){\n const el=$(\"#dessertProducts\");if(!el)return;\n if(!state.dessertProducts.length){el.innerHTML='<div class=\"signatureEmpty\">No catering desserts found.<\/div>';return}\n el.innerHTML=state.dessertProducts.map(p=>{let q=state.desserts[p.id]||0;return `<div class=\"dessertCard${q?\" active\":\"\"}\" data-dessert-card=\"${p.id}\"><img loading=\"lazy\" src=\"${esc(p.image)}\" alt=\"${esc(p.name)}\" loading=\"lazy\" decoding=\"async\" width=\"220\" height=\"220\"><strong>${esc(p.name)}<\/strong><div class=\"dessertPrice\">${money(p.price)} \/ item<\/div><div class=\"dessertMin\">Minimum order: ${p.minimum} pieces<\/div><div class=\"dessertQty\"><button type=\"button\" data-dessert=\"${p.id}\" data-change=\"-1\" aria-label=\"Remove ${esc(p.name)}\">\u2212<\/button><span data-dessert-qty=\"${p.id}\">${q}<\/span><button type=\"button\" data-dessert=\"${p.id}\" data-change=\"1\" aria-label=\"Add ${esc(p.name)}\">+<\/button><\/div><\/div>`}).join(\"\");\n}\n$(\"#dessertProducts\").addEventListener(\"click\",e=>{\n const b=e.target.closest(\"button[data-dessert]\");if(!b)return;\n const id=b.dataset.dessert,p=state.dessertProducts.find(x=>String(x.id)===id);\n if(!p)return;\n const old=state.desserts[id]||0,dir=Number(b.dataset.change);\n const next=dir>0?old+p.minimum:Math.max(0,old-p.minimum);\n if(next)state.desserts[id]=next;else delete state.desserts[id];\n const card=b.closest(\".dessertCard\");card.classList.toggle(\"active\",!!next);\n card.querySelector(\"[data-dessert-qty]\").textContent=next;\n update();\n});\nasync function loadDesserts(){try{let d=await api({action:'cc_get_catering_desserts'});if(!d.success)throw new Error(d.data?.message||'Could not load desserts.');state.dessertProducts=d.data.products||[];renderDesserts();update()}catch(e){$('#dessertProducts').innerHTML=`<div class=\"signatureEmpty\">${esc(e.message)}<\/div>`}}\n\ndocument.querySelectorAll('input[name=\"paymentChoice\"]').forEach(r=>r.addEventListener(\"change\",()=>{state.paymentChoice=r.value;update()}));\n$(\"#minus\").addEventListener(\"click\",()=>{$(\"#qty\").value=Math.max(0,+$(\"#qty\").value-5);update()});$(\"#plus\").addEventListener(\"click\",()=>{$(\"#qty\").value=Math.max(0,+$(\"#qty\").value+5);update()});$$(\".pill\").forEach(p=>p.addEventListener(\"click\",()=>{$(\"#qty\").value=p.dataset.q;update()}));$(\"#qty\").addEventListener(\"input\",update);\n\nconst time=$(\"#eventTime\"),timePicker=$(\"#timePicker\"),timeGrid=$(\"#timeGrid\"),timeDisplay=$(\"#timeDisplay\"),timeText=$(\"#timeText\");\nconst timeValues=[];\n\/\/ Available start times: 8:00 AM through 11:30 PM, plus 12:00 AM (midnight).\nfor(let h=8;h<=23;h++){\n  for(let m of [0,30]) timeValues.push(String(h).padStart(2,\"0\")+\":\"+String(m).padStart(2,\"0\"));\n}\ntimeValues.push(\"00:00\");\n\nfunction renderTimeSlots(blocked=[]){\n  \/\/ Preserve the selected value before rebuilding the hidden select.\n  const selectedTime=time.value;\n\n  timeGrid.innerHTML=\"\";\n  time.innerHTML='<option value=\"\">Select start time<\/option>';\n\n  timeValues.forEach(v=>{\n    const disabled=blocked.includes(v);\n\n    const o=document.createElement(\"option\");\n    o.value=v;\n    o.textContent=timeLabel(v);\n    o.disabled=disabled;\n    time.appendChild(o);\n\n    const b=document.createElement(\"button\");\n    b.type=\"button\";\n    b.className=\"timeSlot\"+(selectedTime===v?\" selected\":\"\");\n    b.dataset.time=v;\n    b.disabled=disabled;\n    b.innerHTML=`<strong>${timeLabel(v)}<\/strong><small>${disabled?\"Unavailable\":\"Available\"}<\/small>`;\n\n    b.addEventListener(\"click\",async()=>{\n      if(b.disabled)return;\n\n      \/\/ Set and KEEP the selected time.\n      time.value=v;\n      timeText.textContent=timeLabel(v);\n      timeDisplay.classList.remove(\"placeholder\");\n      timePicker.classList.remove(\"open\");\n\n      update();\n\n      \/\/ Create\/refresh the hold while the selected value is still present.\n      if(state.date){\n        const held=await holdSlot();\n        if(!held)return;\n      }\n\n      \/\/ Re-render after hold, preserving the selected value.\n      renderTimeSlots(blocked);\n      time.value=v;\n    });\n\n    timeGrid.appendChild(b);\n  });\n\n  \/\/ Restore the value after rebuilding all <option> elements.\n  if(selectedTime && !blocked.includes(selectedTime)){\n    time.value=selectedTime;\n  }\n}\nrenderTimeSlots();\nfunction showTimeLoading(){\n  timeGrid.innerHTML=`<div class=\"timeLoading\"><b>Checking availability\u2026<\/b>Please wait a moment.<\/div>`;\n}\n\ntimeDisplay.addEventListener(\"click\",async()=>{\n  if(!state.date){\n    $(\"#err1\").textContent=\"Please select the event date first.\";\n    $(\"#err1\").style.display=\"block\";\n    return;\n  }\n  if(timePicker.classList.contains(\"open\")){timePicker.classList.remove(\"open\");return;}\n  timePicker.classList.add(\"open\");\n  showTimeLoading();\n  await refreshTimes();\n});\n$(\"#timeClose\").addEventListener(\"click\",()=>timePicker.classList.remove(\"open\"));\n\nasync function refreshTimes(){\n  if(!state.date)return;\n  showTimeLoading();\n  try{\n    let data=await api({action:\"cc_get_unavailable_slots\",event_date:state.date,hold_token:token()});\n    let blocked=data.success&&data.data?data.data.times||[]:[];\n    let dayUnavailable=!!(data.success&&data.data&&data.data.day_unavailable);\n\n    if(dayUnavailable){\n      time.value=\"\";\n      timeText.textContent=\"Date unavailable\";\n      timeDisplay.classList.add(\"placeholder\");\n      renderTimeSlots(blocked);\n      const notice=document.createElement(\"div\");\n      notice.className=\"timeLoading\";\n      notice.innerHTML=\"<b>This date is already booked.<\/b>Please choose another event date. Only one catering booking is accepted per day.\";\n      timeGrid.prepend(notice);\n    }else{\n      if(blocked.includes(time.value)){\n        time.value=\"\";\n        timeText.textContent=\"Select start time\";\n        timeDisplay.classList.add(\"placeholder\");\n      }\n      renderTimeSlots(blocked);\n    }\n  }catch(e){\n    timeGrid.innerHTML=`<div class=\"timeLoading\"><b>Could not load availability.<\/b>Please close and try again.<\/div>`;\n  }\n  update();\n}\nasync function releaseHold(){if(!state.date||!state.holdToken)return;try{await api({action:\"cc_release_booking_hold\",hold_token:state.holdToken})}catch(e){}state.holdExpires=0;$(\"#slotTimer\").classList.remove(\"show\")}\nasync function holdSlot(){if(!state.date||!time.value)return false;let data=await api({action:\"cc_hold_booking_slot\",event_date:state.date,event_time:time.value,hold_token:token()});if(!data.success){$(\"#err1\").textContent=data.data?.message||\"That time is unavailable. Please choose another.\";$(\"#err1\").style.display=\"block\";await refreshTimes();return false}state.holdExpires=+data.data.expires_at_ms;startTimer();$(\"#err1\").style.display=\"none\";return true}\nfunction startTimer(){if(countdownHandle)clearInterval(countdownHandle);let box=$(\"#slotTimer\");box.classList.add(\"show\");box.classList.remove(\"expired\");box.querySelector(\"span\").textContent=\"Your date & time are held for checkout.\";let tick=()=>{let ms=Math.max(0,state.holdExpires-Date.now()),s=Math.ceil(ms\/1000);$(\"#countdown\").textContent=String(Math.floor(s\/60)).padStart(2,\"0\")+\":\"+String(s%60).padStart(2,\"0\");if(ms<=0){clearInterval(countdownHandle);box.classList.add(\"expired\");box.querySelector(\"span\").textContent=\"Your 5-minute hold expired. Please select the time again.\";$(\"#countdown\").textContent=\"00:00\";state.holdExpires=0;if(step>1){step=1;renderStep()}refreshTimes()}};tick();countdownHandle=setInterval(tick,1000)}\n\nconst cal=$(\"#calendar\"),days=$(\"#calDays\"),title=$(\"#calTitle\"),dateDisplay=$(\"#dateDisplay\"),dateText=$(\"#dateText\");\nconst minDate=new Date();minDate.setHours(0,0,0,0);minDate.setDate(minDate.getDate()+7);\nlet vy=minDate.getFullYear(),vm=minDate.getMonth();\nlet unavailableDates=new Set();\nlet calendarLoadSeq=0;\nfunction iso(y,m,d){return y+\"-\"+String(m+1).padStart(2,\"0\")+\"-\"+String(d).padStart(2,\"0\")}\nfunction showCalendarLoading(){\n  title.textContent=new Date(vy,vm,1).toLocaleDateString(\"en-AE\",{month:\"long\",year:\"numeric\"});\n  days.innerHTML=`<div class=\"calLoading\"><b>Checking available dates\u2026<\/b>Please wait a moment.<\/div>`;\n}\nasync function loadMonthAvailability(){\n  const seq=++calendarLoadSeq;\n  showCalendarLoading();\n  try{\n    const data=await api({\n      action:\"cc_get_unavailable_dates\",\n      year:vy,\n      month:vm+1,\n      hold_token:token()\n    });\n    if(seq!==calendarLoadSeq)return;\n    unavailableDates=new Set(data.success&&data.data?data.data.dates||[]:[]);\n  }catch(e){\n    if(seq!==calendarLoadSeq)return;\n    unavailableDates=new Set();\n  }\n  if(seq===calendarLoadSeq)renderCal();\n}\nfunction renderCal(){\n  title.textContent=new Date(vy,vm,1).toLocaleDateString(\"en-AE\",{month:\"long\",year:\"numeric\"});\n  days.innerHTML=\"\";\n  let first=new Date(vy,vm,1).getDay(),count=new Date(vy,vm+1,0).getDate();\n  for(let i=0;i<first;i++){let x=document.createElement(\"button\");x.className=\"day empty\";x.type=\"button\";days.appendChild(x)}\n  for(let d=1;d<=count;d++){\n    let dt=new Date(vy,vm,d);dt.setHours(0,0,0,0);\n    let b=document.createElement(\"button\");b.type=\"button\";b.className=\"day\";b.textContent=d;\n    let iv=iso(vy,vm,d);\n    if(dt<minDate)b.disabled=true;\n    if(unavailableDates.has(iv)){b.disabled=true;b.classList.add(\"unavailable\");b.title=\"Already booked\"}\n    if(iv===state.date&&!b.disabled)b.classList.add(\"selected\");\n    b.addEventListener(\"click\",async()=>{\n      if(b.disabled)return;\n      await releaseHold();\n      state.date=iv;\n      $(\"#eventDate\").value=iv;\n      dateText.textContent=formatDate(iv);\n      dateDisplay.classList.remove(\"placeholder\");\n      cal.classList.remove(\"open\");\n      time.value=\"\";\n      timeText.textContent=\"Select start time\";\n      timeDisplay.classList.add(\"placeholder\");\n      renderCal();\n      await refreshTimes();\n      update();\n    });\n    days.appendChild(b)\n  }\n  $(\"#prevMonth\").disabled=(vy*12+vm)<=(minDate.getFullYear()*12+minDate.getMonth())\n}\ndateDisplay.addEventListener(\"click\",async()=>{\n  if(cal.classList.contains(\"open\")){cal.classList.remove(\"open\");return}\n  cal.classList.add(\"open\");\n  await loadMonthAvailability();\n});\n$(\"#prevMonth\").addEventListener(\"click\",async()=>{if($(\"#prevMonth\").disabled)return;vm--;if(vm<0){vm=11;vy--}await loadMonthAvailability()});\n$(\"#nextMonth\").addEventListener(\"click\",async()=>{vm++;if(vm>11){vm=0;vy++}await loadMonthAvailability()});\ndocument.addEventListener(\"click\",e=>{if(!e.target.closest(\".dateWrap\"))cal.classList.remove(\"open\");if(!e.target.closest(\".timeWrap\"))timePicker.classList.remove(\"open\")});\nrenderCal();\n\nconst modal=document.getElementById(\"termsModal\");$(\"#openTerms\").addEventListener(\"click\",()=>modal.classList.add(\"open\"));document.getElementById(\"closeTerms\").addEventListener(\"click\",()=>modal.classList.remove(\"open\"));modal.addEventListener(\"click\",e=>{if(e.target===modal)modal.classList.remove(\"open\")});\n\nasync function pay(){if(!state.holdExpires||Date.now()>=state.holdExpires){$(\"#err5\").textContent=\"Your reservation hold expired. Please select the date and time again.\";$(\"#err5\").style.display=\"block\";step=1;renderStep();return}let btn=$(\"#pay\"),mob=$(\"#mobileAction\");btn.disabled=true;mob.disabled=true;$(\"#loader\").style.display=\"block\";let f=new URLSearchParams();f.set(\"action\",\"cc_event_booking_add_to_cart\");f.set(\"hold_token\",token());f.set(\"event_date\",state.date);f.set(\"event_time\",time.value);f.set(\"venue\",$(\"#venue\").value.trim());f.set(\"emirate_key\",state.emirateKey);f.set(\"cup_type\",state.cup);f.set(\"quantity\",state.qty);f.set(\"customization\",state.custom);f.set(\"female_barista\",$(\"#femaleBarista\").checked?\"yes\":\"no\");f.set(\"customer_name\",$(\"#name\").value.trim());f.set(\"customer_phone\",$(\"#phone\").value.trim());f.set(\"customer_email\",$(\"#email\").value.trim());f.set(\"terms_accepted\",$(\"#terms\").checked?\"yes\":\"no\");f.set(\"contact_consent\",$(\"#contactConsent\").checked?\"yes\":\"no\");f.set(\"signature_ids\",JSON.stringify(state.signatures));f.set(\"desserts\",JSON.stringify(state.desserts));f.set(\"payment_choice\",state.paymentChoice);try{let r=await fetch(\"\/wp-admin\/admin-ajax.php\",{method:\"POST\",headers:{\"Content-Type\":\"application\/x-www-form-urlencoded; charset=UTF-8\"},body:f.toString(),credentials:\"same-origin\"}),d=await r.json();if(d.success&&d.data?.checkout_url){location.href=d.data.checkout_url;return}throw new Error(d.data?.message||\"Could not prepare checkout.\")}catch(e){$(\"#loader\").style.display=\"none\";$(\"#err5\").textContent=e.message;$(\"#err5\").style.display=\"block\";btn.disabled=false;mob.disabled=false}}\n$(\"#pay\").addEventListener(\"click\",pay);\n\/\/ Allow the event form to render and respond before fetching catalogue products.\nconst loadCatalogue=()=>{loadSignatures();loadDesserts()};\nif(\"requestIdleCallback\" in window){requestIdleCallback(loadCatalogue,{timeout:1200})}\nelse{setTimeout(loadCatalogue,0)}\nupdate();\n})();\n<\/script>\n<\/body>\n<\/html>\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>Catering Event Booking Secure WooCommerce checkout Full booking totalSelect booking 1 EVENT 2 ORDER 3 REVIEW 4 PAY Your date &#038; time are held for checkout.05:00 Step 01 \u2014 Event details When and where? Bookings can be made from 7 days ahead. Each booking includes 5 hours on-site. We accept one catering booking per day. [&hellip;]<\/p>\n","protected":false},"author":2,"featured_media":0,"parent":0,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"","meta":{"footnotes":""},"class_list":["post-1253","page","type-page","status-publish","hentry"],"blocksy_meta":{"styles_descriptor":{"styles":{"desktop":"","tablet":"","mobile":""},"google_fonts":[],"version":8}},"_links":{"self":[{"href":"https:\/\/chachamatcha.ae\/ar\/wp-json\/wp\/v2\/pages\/1253","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/chachamatcha.ae\/ar\/wp-json\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/chachamatcha.ae\/ar\/wp-json\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/chachamatcha.ae\/ar\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/chachamatcha.ae\/ar\/wp-json\/wp\/v2\/comments?post=1253"}],"version-history":[{"count":55,"href":"https:\/\/chachamatcha.ae\/ar\/wp-json\/wp\/v2\/pages\/1253\/revisions"}],"predecessor-version":[{"id":1366,"href":"https:\/\/chachamatcha.ae\/ar\/wp-json\/wp\/v2\/pages\/1253\/revisions\/1366"}],"wp:attachment":[{"href":"https:\/\/chachamatcha.ae\/ar\/wp-json\/wp\/v2\/media?parent=1253"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}