1<!DOCTYPE html><html data-prerendered lang="en-GB" class="light" style="color-scheme: light;"><head> 2 <meta charset="UTF-8"> 3 <!-- Real-touch detection, before first paint. 4 The anti-rubber-band CSS in src/index.css moves the page's scroll 5 container onto <body>, which is right for a phone and fatal on a 6 laptop: the page stops responding to two-finger scrolling while arrow 7 keys still work. It used to be gated on media features alone, and an 8 older Intel MacBook's Safari reports `pointer: coarse` AND 9 `hover: none` â so it took the phone treatment and could not scroll 10 (reported twice: 2026-08-15, and again 2026-08-31 on the build that 11 was meant to have fixed it). 12 `maxTouchPoints` is hardware, not a claim: 0 on every MacBook, 5 on an 13 iPhone. Inline and synchronous so the class is on <html> before the 14 first paint, and in the shell so it covers all three built pages. 15 Pinned by tests/touch-scroll-model-gate.test.ts. --> 16
16<script> 17 (function () { 18 try { 19 if ((navigator.maxTouchPoints || 0) > 0) { 20 document.documentElement.classList.add('is-touch'); 21 } 22 } catch (e) { 23 /* Fail SAFE: no class means a phone may rubber-band, which is 24 cosmetic. The alternative â a laptop that cannot scroll â is not. */ 25 } 26 })(); 27 </script>
27 28 <!-- RESOFLOW-TRANSLATE-GUARD â browser-translation safety net. 29 30 Google Translate, and the built-in translators in Chrome / Edge / 31 Safari, do NOT translate text where it sits. They lift each text node 32 into a wrapper element of their own and put the translation inside 33 that. React still holds a reference to the ORIGINAL node and to the 34 parent it put that node in, so the next render calls 35 parent.removeChild(node) â or parent.insertBefore(next, node) â for a 36 node that now lives one level deeper. The DOM throws NotFoundError, 37 React tears down the route subtree, and the venue is left staring at 38 a blank page in the middle of whatever they were doing. Sentry has 39 the pair from real production traffic (RESOFLOW-FRONTEND-44/46/47), 40 including both halves during one genuine signup. 41 42 SCOPE, and why it is this and not `notranslate`: 43 - It patches exactly the TWO methods that throw, and only on the 44 branch where the node is already somewhere other than where the 45 caller believes it is. That state cannot occur in a healthy 46 document, so for every visitor who is NOT translating this is a 47 no-op â it never changes a single DOM operation. 48 - NOTHING is marked notranslate, anywhere. Marking the app (or any 49 part of it a venue actually reads) would "fix" the crash by 50 taking translation away from the exact people it exists to 51 protect â a Vietnamese owner who needs the sidebar, the settings 52 copy and the setup wizard in their own language. The app stays 53 fully translatable; only the breakage is removed. 54 - Nothing else on the platform is exposed: the guest widget embeds 55 a cross-origin iframe and only ever appends, the body-level 56 overlays (human-check card, chunk-error notice) are appended once 57 and removed whole, and the static 404 page runs no JS. 58 59 It lives in the shell rather than the bundle so it is installed 60 before React, before any route chunk, and before hydration; and 61 because all three shells (dist/index.html, dist/app.html and 62 dist-admin/index.html) are built from THIS file, one copy covers the 63 tenant SPA, the public pages and the admin panel. 64 Pinned by tests/browser-translation-guard.test.ts. --> 65
65<script> 66 (function () { 67 var P = Node.prototype; 68 var nativeRemoveChild = P.removeChild; 69 var nativeInsertBefore = P.insertBefore; 70 P.removeChild = function (child) { 71 if (child && child.parentNode !== this) { 72 // Translated: the node was moved into the translator's wrapper. 73 // Remove it from where it ACTUALLY is â React wanted it gone. 74 if (child.parentNode) child.parentNode.removeChild(child); 75 return child; 76 } 77 return nativeRemoveChild.apply(this, arguments); 78 }; 79 P.insertBefore = function (newNode, referenceNode) { 80 if (referenceNode && referenceNode.parentNode !== this) { 81 // Insert at the reference node's real position, so the new 82 // content still lands where the reader should see it. 83 if (referenceNode.parentNode) { 84 return referenceNode.parentNode.insertBefore(newNode, referenceNode); 85 } 86 return this.appendChild(newNode); 87 } 88 return nativeInsertBefore.apply(this, arguments); 89 }; 90 })(); 91 </script>
91 92 <!-- P-cloudflare-pro-and-hardening Stage G1: per-hostname noindex. 93 Injects a robots meta tag (noindex,nofollow,nosnippet,noarchive) â 94 described in prose, never as markup: tag-shaped text in a comment is 95 runaway-comment fuel for the og-shell strip (gotcha #72; tripwired by 96 tests/share-shell-parse.test.ts) â 97 for any non-production host (staging custom domains, Firebase temp URLs, 98 preview channels). Prod resoflow.co.uk is unaffected â normal indexing. 99 Static /public/robots.txt is the belt-and-braces fallback for crawlers 100 that don't run JS. 101 IMPORTANT â guarded against the build-time PRERENDER snapshot: the 102 prerenderer runs this page in headless Chrome and SERIALISES the DOM, so 103 without the __PRERENDER_INJECTED guard the injected noindex was getting 104 baked into the static prod HTML (resoflow.co.uk shipped noindex â the 105 whole site dropped from Google). The flag is set by puppeteer's 106 evaluateOnNewDocument BEFORE this script runs (see src/utils/prerender.ts), 107 and is ALWAYS absent at real runtime, so live staging/.web.app hosts 108 still get the noindex exactly as before. --> 109
109<script> 110 (function () { 111 var pr = window.__PRERENDER_INJECTED; 112 if (pr && pr.prerender) return; // build-time snapshot: never bake noindex 113 var h = window.location.hostname; 114 if ( 115 h.indexOf('staging') !== -1 || 116 h.endsWith('.web.app') || 117 h.endsWith('.firebaseapp.com') 118 ) { 119 var m = document.createElement('meta'); 120 m.name = 'robots'; 121 m.content = 'noindex,nofollow,nosnippet,noarchive'; 122 document.head.appendChild(m); 123 } 124 })(); 125 </script>
125 126 <meta name="viewport" content="width=device-width, initial-scale=1.0, viewport-fit=cover"> 127 <!-- Favicon set (razor-sharp from the vector master public/brand/resoflow-icon.svg 128 via scripts/generate-icon-kit.mjs). favicon.svg is vector (sharpest in modern 129 browsers); favicon.ico embeds native 16/32/48 so Google + browser tabs pick the 130 exact raster size instead of downscaling one PNG (the old blurry-in-search bug). --> 131 <link rel="icon" href="/favicon.ico" sizes="any"> 132 <link rel="icon" type="image/svg+xml" href="/favicon.svg"> 133 <link rel="icon" type="image/png" sizes="96x96" href="/icons/favicon-96x96.png"> 134 <link rel="icon" type="image/png" sizes="32x32" href="/icons/favicon-32x32.png"> 135 <link rel="icon" type="image/png" sizes="16x16" href="/icons/favicon-16x16.png"> 136 <link rel="apple-touch-icon" sizes="180x180" href="/icons/apple-touch-icon-180.png"> 137 <!-- iOS "Add to Home Screen" names the shortcut from apple-mobile-web-app-title 138 FIRST (then the manifest name / the title tag / the bare URL). Our title and 139 manifest link are set by JS after load, so iOS sometimes caught the page too 140 early and fell through to showing the bare "resoflow.co.uk/portal". These 141 STATIC tags are read immediately, making the shortcut name deterministic 142 ("ResoFlow") on every device + route. Fixed 2026-07-01. 143 NEVER write a literal title/meta/link TAG inside an HTML comment in this 144 file: the og-shell strip regexes (functions/src/server/newsSeo.ts) operate 145 on this file's built output, and a tag-shaped string inside a comment 146 corrupted the parse of every share-shell page (staging incident 2026-07-22). --> 147 <!-- Both tags deliberately present: the modern name silences Chrome's 148 deprecation warning; the apple- one keeps older iOS standalone mode. --> 149 <meta name="mobile-web-app-capable" content="yes"> 150 <meta name="apple-mobile-web-app-capable" content="yes"> 151 <meta name="apple-mobile-web-app-title" content="ResoFlow"> 152 <!-- R194 (DA-1310, 2026-07-29): 'default' (was 'black-translucent', which 153 predated the 2026-07-01 switch to a light default theme) â the 154 translucent bar drew the clock/signal/battery in WHITE over the 155 near-white app, unreadable on the iPads staff use every shift. --> 156 <meta name="apple-mobile-web-app-status-bar-style" content="default"> 157 <!-- WS-9 T-9.1 â per-surface PWA install. ONE SPA shell serves every 158 surface, so the manifest link is adjusted per-path BEFORE Chromium 159 evaluates installability. ONE app since Q142 (15 Sep 2026 â it 160 REVERSES FA-R338's two-app split; pinned by 161 tests/portal-pwa-install.test.ts): 162 /dashboard*, /portal*, /app -> the ONE "ResoFlow" manifest 163 (/manifest-dashboard.json â scope /, start_url /app; the 164 filename is kept so an installed app updates in place). 165 /login -> link NOT added (R15 F10 â the browser must never offer 166 an install on the sign-in page). 167 the ADMIN HOST -> link NOT added (the admin router has no 168 /portal route â an installed app opened Page-Not-Found; 169 R194/DA-1311). 170 everything else (the marketing homepage, public 171 booking/event/ticket/waitlist pages, policies) -> link NOT 172 added, so the browser never offers an ambient install on 173 public customer pages (DA-1282 removed '/' from the list). 174 SPA navigations after load are kept in sync by syncManifestForPath() 175 in src/utils/surfaceManifest.ts â keep BOTH in step if the rules 176 change. Runs inline (pre-parse of the bundle) because Chromium reads 177 the manifest early. The old token-baked /portal-manifest/<token> 178 link is no longer attached anywhere (the endpoint keeps serving for 179 tablets that installed the old "ResoFlow Staff" app â Q153); the 180 app's first screen is the person's choice, resolved by /app. --> 181
181<script> 182 (function () { 183 var p = window.location.pathname; 184 // Admin host? Mirrors getIsAdminMode() (and the theme script below) â 185 // the admin SPA has no /portal route, so a manifest here produced an 186 // installable app that opened Page-Not-Found (R194/DA-1311). 187 var host = window.location.hostname; 188 var firstLabel = host.split('.')[0]; 189 var isAdminHost = 190 firstLabel === 'admin' || 191 firstLabel.slice(-6) === '-admin' || 192 (host === 'localhost' && window.location.port === '3001') || 193 window.location.search.indexOf('adminMode=1') !== -1; 194 if (isAdminHost) return; 195 // Q142 (2026-09-15) â ONE app: /dashboard*, /portal*, /app â the 196 // ResoFlow manifest; /login and every public page â none. Twin: 197 // src/utils/surfaceManifest.ts (keep BOTH in step). 198 var isApp = p === '/app' || p === '/app/'; 199 var isPortal = p === '/portal' || p.indexOf('/portal/') === 0; 200 var isDashboard = p === '/dashboard' || p.indexOf('/dashboard/') === 0; 201 if (isApp || isPortal || isDashboard) { 202 var l = document.createElement('link'); 203 l.rel = 'manifest'; 204 l.href = '/manifest-dashboard.json'; 205 document.head.appendChild(l); 206 } 207 })(); 208 </script>
208 209 <!-- Theme-aware cold-load splash. Runs BEFORE first paint so a dark-theme 210 user never sees the light #initial-splash flash to a dark page on 211 cold load / sign-in. It: 212 (1) sets html[data-splash] â the <style> above recolours the splash, 213 (2) adds the `.dark` class up-front on dark app shells, so when React 214 mounts next-themes finds it already set and the BrandSplash route 215 fallback is dark immediately (no light-BrandSplash flash either). 216 SCOPING (marketing / public / policy pages must stay light): 217 - /dashboard (+ every path on the admin host) -> 'dark' ONLY 218 when the persisted theme resolves to dark. 219 - /portal ADDITIONALLY requires an active staffSession (A0, 220 2026-07-13) â the unauthenticated PIN screen always stays 221 light, mirroring src/utils/themeRoutePolicy.ts. 222 - everything else -> untouched (stays light). 223 Entry-funnel fix (2026-07-13): /onboarding and /login were REMOVED 224 from the dark-capable list â both are LIGHT-designed funnel doors 225 (OnboardingShell variant="light"), and the old always-dark 226 'onboarding' splash (plus dark-theme /login) was the cold-load half 227 of the "loading screens flash dark mode" bug: dark splash â light 228 page. They now keep the default light splash, matching the light 229 BrandSplash React hands over to (RestrictDarkToDashboard strips 230 .dark on both routes at runtime, so the splash finally agrees with 231 the page). The admin host keeps its dark-capable root â the dark 232 AdminLoginPage lives there, not on the tenant /login. 233 The theme key is next-themes' raw localStorage 'theme' ('light'|'dark' 234 |'system'); missing/unknown = light (matches defaultTheme="light"). 235 Guarded against the PRERENDER snapshot so .dark / data-splash is never 236 baked into a static marketing page (same guard as the noindex script). --> 237
237<script> 238 (function () { 239 try { 240 var pr = window.__PRERENDER_INJECTED; 241 if (pr && pr.prerender) return; // build-time snapshot: never bake theme 242 var p = window.location.pathname; 243 // Admin host detection â mirrors getIsAdminMode() in 244 // src/contexts/AdminModeContext.tsx. The admin SPA (dist-admin) shares 245 // this template and its dark-capable shell is rooted at '/', so on the 246 // admin host EVERY path is a dark-capable shell. 247 var host = window.location.hostname; 248 var firstLabel = host.split('.')[0]; 249 var isAdminHost = 250 firstLabel === 'admin' || 251 firstLabel.slice(-6) === '-admin' || 252 (host === 'localhost' && window.location.port === '3001') || 253 window.location.search.indexOf('adminMode=1') !== -1; 254 // Rule 5b (crew GUEST-TRUTH, 2026-09-11) â a VENUE's guest surface: 255 // the guest route families on ResoFlow's own hosts, or ANY path on a 256 // host that is not ours (a venue's own domain). MIRRORS 257 // src/utils/guestSurfacePath.ts (this script runs before any module 258 // can load); tests/guest-brand-leak.test.ts pins the two in step. 259 // The splash comet + the address-bar colour become the rule-5b 260 // neutral here, before first paint; React's VenueBrandScope then 261 // writes the venue's own accent. ResoFlow's routes keep the pink. 262 var GUEST_PREFIXES = ['/book','/venue','/menu','/order','/events','/event','/ticket','/scan','/gift','/waitlist','/account','/my-bookings','/manage-booking','/pay','/unsubscribe','/wasnt-me','/loyalty-wasnt-me','/find-us','/embed','/order-status']; 263 var h = host.toLowerCase(); 264 var isResoFlowHost = 265 h === 'resoflow.co.uk' || h === 'www.resoflow.co.uk' || h === 'staging.resoflow.co.uk' || 266 h.slice(-8) === '.web.app' || h.slice(-16) === '.firebaseapp.com' || 267 h === 'localhost' || h === '127.0.0.1' || h.slice(-10) === '.localhost'; 268 var isGuestPath = false; 269 for (var gi = 0; gi < GUEST_PREFIXES.length; gi++) { 270 if (p === GUEST_PREFIXES[gi] || p.indexOf(GUEST_PREFIXES[gi] + '/') === 0) { isGuestPath = true; break; } 271 } 272 if (!isAdminHost && (!isResoFlowHost || isGuestPath)) { 273 document.documentElement.setAttribute('data-splash', 'guest'); 274 var themeMeta = document.querySelector('meta[name="theme-color"]:not([media])'); 275 if (themeMeta) themeMeta.setAttribute('content', '#18181B'); 276 return; // a guest surface is light; never the dark-shell logic 277 } 278 // Dark-capable app shells (the only surfaces with a dark-mode pass â 279 // keep in step with src/utils/themeRoutePolicy.ts). On the TENANT 280 // host these are the explicit authed shell prefixes; the tenant '/' 281 // is the marketing homepage and must stay light. 282 // A0 (2026-07-13): /portal is dark-capable ONLY with an active 283 // staff session â mirrors isDarkAllowedPath(pathname, hasStaffSession) 284 // exactly. Without this condition the PIN screen painted a DARK 285 // instant splash for any device whose saved theme is dark, which 286 // React then stripped (the runtime policy denies dark on the 287 // unauthenticated PIN page) â the darkâlight cold-splash flash. 288 var hasStaffSession = false; 289 try { hasStaffSession = !!window.sessionStorage.getItem('staffSession'); } catch (e) {} 290 var isDarkCapableShell = 291 isAdminHost || 292 p === '/dashboard' || p.indexOf('/dashboard/') === 0 || 293 ((p === '/portal' || p.indexOf('/portal/') === 0) && hasStaffSession); 294 if (!isDarkCapableShell) return; // public page / funnel door: stay light 295 var html = document.documentElement; 296 // Dark app shell: apply only when the resolved theme is dark. 297 var stored = null; 298 try { stored = localStorage.getItem('theme'); } catch (e) {} 299 var isDark = 300 stored === 'dark' || 301 (stored === 'system' && 302 window.matchMedia && 303 window.matchMedia('(prefers-color-scheme: dark)').matches); 304 if (isDark) { 305 html.classList.add('dark'); 306 html.setAttribute('data-splash', 'dark'); 307 } 308 } catch (e) { /* never block first paint on a splash-theme error */ } 309 })(); 310 </script>
310 311 <!-- Mobile browser chrome (address bar) colour. R194 (DA-1312, 312 2026-07-29): ONE static light-cyan value â the old 313 prefers-color-scheme dark companion followed the PHONE's dark mode, 314 not the app's own theme (the app defaults to LIGHT and only goes 315 dark on an explicit user/staff choice), so an OS-dark phone got a 316 dark browser bar over a light page. ThemeColorSync in 317 src/contexts/ThemeContext.tsx now updates this tag's content from 318 the app's RESOLVED theme at runtime instead. Manifests keep a 319 single light theme_color (the norm there). Rule 5b (GUEST-TRUTH, 320 2026-09-11): on a venue's guest surface the inline script above 321 sets it to the neutral before first paint and VenueBrandScope then 322 writes the venue's accent; ThemeColorSync stands down there. --> 323 <meta name="theme-color" content="#D94AB0"> 324 <!-- P-fair-usage-phase4c Speed Win 3 â preconnect hints for the most 325 critical 3rd-party origins on public-page cold load. Saves the TCP + 326 TLS handshake on the first request to each origin (~100-200ms per 327 origin on cold network). Both projects are listed because the same 328 bundle ships to both staging + prod hostnames; browsers ignore 329 preconnects to origins they don't end up using. 330 331 homepage-polish W8 / P5 (investigated, deliberately LEFT AS-IS): this 332 <head> is SHARED â the prerenderer bakes it into BOTH the static 333 marketing pages (/, /features, â¦) AND the SPA shell dist/app.html (the 334 `**` -> /app.html fallback that serves /login, /dashboard, /book, all 335 firebase-heavy). So the firebase/auth origins below CANNOT be removed 336 from the marketing pages by a static edit without also stripping them 337 from the app shell that genuinely needs them. They are also NOT purely 338 wasted on marketing: an authed operator browsing a marketing page boots 339 the auth engine (persisted-session hint in authBootPolicy.ts), which 340 reads firestore (user-doc listener) + refreshes tokens (securetoken). 341 For anonymous marketing visitors the unused ones are only idle 342 speculative sockets the browser drops after ~10s (no render/CLS cost). 343 Net: the provably-safe option is document-and-leave â a future agent 344 should NOT naively delete these thinking they're marketing-only. --> 345 346 <link rel="preconnect" href="https://europe-west1-resoflow-prod.cloudfunctions.net" crossorigin=""> 347 <link rel="preconnect" href="https://europe-west1-resoflow-staging.cloudfunctions.net" crossorigin=""> 348 <link rel="preconnect" href="https://challenges.cloudflare.com" crossorigin=""> 349 <link rel="preconnect" href="https://firestore.googleapis.com" crossorigin=""> 350 <!-- Sign-in path: Firebase Auth REST origins (signInWithPassword + token 351 refresh). Without these the FIRST auth request pays a fresh 352 DNS+TCP+TLS handshake on top of the credential round-trip. --> 353 <link rel="preconnect" href="https://identitytoolkit.googleapis.com" crossorigin=""> 354 <link rel="preconnect" href="https://securetoken.googleapis.com" crossorigin=""> 355 <!-- Preload the two Outfit weights used by virtually all first-paint text 356 (body 400 / headings 700) so the FOUT window closes as early as 357 possible. The other weights (300/500/600) load on demand via CSS. --> 358 <link rel="preload" href="/fonts/outfit-400.woff2" as="font" type="font/woff2" crossorigin=""> 359 <link rel="preload" href="/fonts/outfit-700.woff2" as="font" type="font/woff2" crossorigin=""> 360 <!-- 361 Per-page title, description meta, canonical, og:title, og:description 362 and og:url are injected by react-helmet-async via the PageMeta 363 component. Page-agnostic OG/Twitter fallbacks live below. (Comment 364 hygiene: never write tag-shaped title/meta/link text in comments here â 365 see the iOS comment above + tests/share-shell-parse.test.ts.) 366 --> 367 <meta property="og:type" content="website"> 368
369 <meta property="og:image:width" content="1200"> 370 <meta property="og:image:height" content="630"> 371 372 <meta property="og:site_name" content="ResoFlow"> 373 <meta property="og:locale" content="en_GB"> 374 375 376 377 <title>Standalone products â for any business | ResoFlow</title> 378 <!-- Base description for crawlers/first-paint; every route overrides it 379 at runtime via PageMeta (audit A §5.4 insurance line). --> 380 381
381<script type="application/ld+json"> 382 { 383 "@context": "https://schema.org", 384 "@type": "Organization", 385 "@id": "https://resoflow.co.uk/#organization", 386 "name": "ResoFlow", 387 "legalName": "Caleonix LTD", 388 "url": "https://resoflow.co.uk", 389 "logo": "https://resoflow.co.uk/icons/icon-512.png", 390 "description": "The booking and venue platform for independent UK restaurants, cafés, bars and venues.", 391 "address": { 392 "@type": "PostalAddress", 393 "streetAddress": "71-75 Shelton Street", 394 "addressLocality": "London", 395 "postalCode": "WC2H 9JQ", 396 "addressCountry": "GB" 397 }, 398 "contactPoint": { 399 "@type": "ContactPoint", 400 "email": "[email protected]", 401 "contactType": "customer support", 402 "areaServed": "GB", 403 "availableLanguage": "en" 404 }, 405 "sameAs": [ 406 "https://www.instagram.com/resoflowUK", 407 "https://www.facebook.com/resoflow" 408 ], 409 "slogan": "Your bookings. Your venue. One system." 410 } 411 </script>
411 412
412<script type="application/ld+json"> 413 { 414 "@context": "https://schema.org", 415 "@type": "SoftwareApplication", 416 "name": "ResoFlow", 417 "applicationCategory": "BusinessApplication", 418 "applicationSubCategory": "Reservation and Venue Management Software", 419 "operatingSystem": "Web", 420 "url": "https://resoflow.co.uk", 421 "description": "All-in-one reservation, waitlist, floor-plan, events and guest-CRM platform for restaurants, cafés, bars and venues in the UK.", 422 "featureList": [ 423 "Online reservations and embeddable booking widget", 424 "Waitlist management", 425 "Interactive floor plans and table management", 426 "Events and ticketing", 427 "Guest CRM and email marketing", 428 "Automated SMS and email confirmations", 429 "Deposits and no-show protection", 430 "Gift cards", 431 "Loyalty scheme with Apple and Google Wallet cards", 432 "Order & Pay â QR table ordering, collection and delivery", 433 "Promotions and offer codes", 434 "Themed venue website", 435 "Custom domain for the venue's pages" 436 ] 437 } 438 </script>
438 439
439<script type="application/ld+json"> 440 { 441 "@context": "https://schema.org", 442 "@type": "WebSite", 443 "@id": "https://resoflow.co.uk/#website", 444 "name": "ResoFlow", 445 "url": "https://resoflow.co.uk", 446 "publisher": { "@id": "https://resoflow.co.uk/#organization" } 447 } 448 </script>
448 449 <style> 450 /* Instant-paint splash â visible the moment the HTML arrives, before the 451 JS bundle parses. React (createRoot) replaces #root's children on 452 mount, removing it. Matches BrandSplash EXACTLY â same slate-50 453 background AND the same TRULY-CENTRED loader position (R-SPINNER, 454 2026-07-23: the whole splash family is viewport-centred now; the old 455 top-aligned pt-24/sm:pt-32 design is superseded) â so the handoff 456 #initial-splash â BrandSplash never moves the spinner. The spinner 457 is the dependency-free CSS twin of ui/BrandSpinner (brand-gradient 458 conic arc over a faint track) â keep the two visually matched. 459 No JS, no asset dependency. */ 460 #initial-splash{position:fixed;inset:0;display:flex;flex-direction:column;align-items:center;justify-content:center;background:#f8fafc} 461 #initial-splash .rf-sp{position:relative;width:48px;height:48px} 462 #initial-splash .rf-sp::before{content:"";position:absolute;inset:0;border-radius:9999px;border:5px solid #e2e8f0} 463 #initial-splash .rf-sp::after{content:"";position:absolute;inset:0;border-radius:9999px;background:conic-gradient(from 0deg,rgba(217,74,176,0) 0deg,rgba(217,74,176,0) 120deg,#BE185D 190deg,#D94AB0 285deg,#E968C1 360deg);-webkit-mask:radial-gradient(farthest-side,transparent calc(100% - 5px),#000 calc(100% - 4.5px));mask:radial-gradient(farthest-side,transparent calc(100% - 5px),#000 calc(100% - 4.5px));animation:rf-spin .9s linear infinite} 464 @keyframes rf-spin{to{transform:rotate(360deg)}} 465 /* Reduced motion: the arc rests static â matching BrandSpinner's 466 motion-reduce:animate-none posture. The global clamp can't reach 467 this pre-CSS window, so the guard lives inline (AU3-1). */ 468 @media (prefers-reduced-motion: reduce){#initial-splash .rf-sp::after{animation:none}} 469 /* Theme-aware splash (set by the inline script below BEFORE first paint, 470 so a dark-theme user never sees a light splash â dark page flash). 471 Scoped by html[data-splash]; public + prerendered marketing pages â 472 and, since the entry-funnel fix (2026-07-13), the light-designed 473 /onboarding + /login funnel doors â never get the attribute, so they 474 stay light. dark = dashboard/portal (+ admin host) when theme is dark 475 (slate-900, matching BrandSplash dark:bg-slate-900). The old 476 html[data-splash="onboarding"] dark-gradient rules were removed with 477 the dark funnel design (the splash no longer disagrees with the 478 light page it hands over to). */ 479 html[data-splash="dark"] #initial-splash{background:#0f172a} 480 html[data-splash="dark"] #initial-splash .rf-sp::before{border-color:#1e293b} 481 /* Rule 5b (crew GUEST-TRUTH, 2026-09-11): a VENUE's guest surface never 482 wears a ResoFlow colour â the pre-JS comet used to be pink on every 483 venue URL (their own domain included). html[data-splash="guest"] is 484 set by the inline script below for the guest route families and for 485 ANY host that is not ResoFlow's own; the arc is then the rule-5b 486 neutral (#18181B â VENUE_ACCENT_FALLBACK), the same comet the 487 guest-tone BrandSpinner draws once React paints. Light only: guest 488 pages are forced light. */ 489 html[data-splash="guest"] #initial-splash .rf-sp::after{background:conic-gradient(from 0deg,rgba(24,24,27,0) 0deg,rgba(24,24,27,0) 120deg,#18181B 190deg,#18181B 285deg,#52525B 360deg)} 490 </style> 491
491<script type="module" crossorigin="" src="/assets/index-CJ0eVksD.js"></script>
491 492 <link rel="modulepreload" crossorigin="" href="/assets/vendor-react-Cg5IBgwO.js"> 493 <link rel="stylesheet" crossorigin="" href="/assets/index-BbrDgIPv.css"> 494 <meta name="app-version" content="1.0.0"> 495 <meta name="build-date" content="2026-09-25T10:58:53.668Z"> 496 <style type="text/css">
vendor: 14,859 bytes, line 496
496[data-sonner-toaster][dir=ltr],html[dir=ltr]{--toast-icon-margin-start:-3px;--toast-icon-margin-end:4px;--toast-svg-margin-start:-1px;--toast-svg-margin-end:0px;--toast-button-margin-start:auto;--toast-button-margin-end:0;--toast-close-button-start:0;--toast-close-button-end:unset;--toast-close-button-transform:translate(-35%, -35%)}[data-sonner-toaster][dir=rtl],html[dir=rtl]{--toast-icon-margin-start:4px;--toast-icon-margin-end:-3px;--toast-svg-margin-start:0px;--toast-svg-margin-end:-1px;--toast-button-margin-start:0;--toast-button-margin-end:auto;--toast-close-button-start:unset;--toast-close-button-end:0;--toast-close-button-transform:translate(35%, -35%)}[data-sonner-toaster]{position:fixed;width:var(--width);font-family:ui-sans-serif,system-ui,-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Helvetica Neue,Arial,Noto Sans,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol,Noto Color Emoji;--gray1:hsl(0, 0%, 99%);--gray2:hsl(0, 0%, 97.3%);--gray3:hsl(0, 0%, 95.1%);--gray4:hsl(0, 0%, 93%);--gray5:hsl(0, 0%, 90.9%);--gray6:hsl(0, 0%, 88.7%);--gray7:hsl(0, 0%, 85.8%);--gray8:hsl(0, 0%, 78%);--gray9:hsl(0, 0%, 56.1%);--gray10:hsl(0, 0%, 52.3%);--gray11:hsl(0, 0%, 43.5%);--gray12:hsl(0, 0%, 9%);--border-radius:8px;box-sizing:border-box;padding:0;margin:0;list-style:none;outline:0;z-index:999999999;transition:transform .4s ease}@media (hover:none) and (pointer:coarse){[data-sonner-toaster][data-lifted=true]{transform:none}}[data-sonner-toaster][data-x-position=right]{right:var(--offset-right)}[data-sonner-toaster][data-x-position=left]{left:var(--offset-left)}[data-sonner-toaster][data-x-position=center]{left:50%;transform:translateX(-50%)}[data-sonner-toaster][data-y-position=top]{top:var(--offset-top)}[data-sonner-toaster][data-y-position=bottom]{bottom:var(--offset-bottom)}[data-sonner-toast]{--y:translateY(100%);--lift-amount:calc(var(--lift) * var(--gap));z-index:var(--z-index);position:absolute;opacity:0;transform:var(--y);touch-action:none;transition:transform .4s,opacity .4s,height .4s,box-shadow .2s;box-sizing:border-box;outline:0;overflow-wrap:anywhere}[data-sonner-toast][data-styled=true]{padding:16px;background:var(--normal-bg);border:1px solid var(--normal-border);color:var(--normal-text);border-radius:var(--border-radius);box-shadow:0 4px 12px rgba(0,0,0,.1);width:var(--width);font-size:13px;display:flex;align-items:center;gap:6px}[data-sonner-toast]:focus-visible{box-shadow:0 4px 12px rgba(0,0,0,.1),0 0 0 2px rgba(0,0,0,.2)}[data-sonner-toast][data-y-position=top]{top:0;--y:translateY(-100%);--lift:1;--lift-amount:calc(1 * var(--gap))}[data-sonner-toast][data-y-position=bottom]{bottom:0;--y:translateY(100%);--lift:-1;--lift-amount:calc(var(--lift) * var(--gap))}[data-sonner-toast][data-styled=true] [data-description]{font-weight:400;line-height:1.4;color:#3f3f3f}[data-rich-colors=true][data-sonner-toast][data-styled=true] [data-description]{color:inherit}[data-sonner-toaster][data-sonner-theme=dark] [data-description]{color:#e8e8e8}[data-sonner-toast][data-styled=true] [data-title]{font-weight:500;line-height:1.5;color:inherit}[data-sonner-toast][data-styled=true] [data-icon]{display:flex;height:16px;width:16px;position:relative;justify-content:flex-start;align-items:center;flex-shrink:0;margin-left:var(--toast-icon-margin-start);margin-right:var(--toast-icon-margin-end)}[data-sonner-toast][data-promise=true] [data-icon]>svg{opacity:0;transform:scale(.8);transform-origin:center;animation:sonner-fade-in .3s ease forwards}[data-sonner-toast][data-styled=true] [data-icon]>*{flex-shrink:0}[data-sonner-toast][data-styled=true] [data-icon] svg{margin-left:var(--toast-svg-margin-start);margin-right:var(--toast-svg-margin-end)}[data-sonner-toast][data-styled=true] [data-content]{display:flex;flex-direction:column;gap:2px}[data-sonner-toast][data-styled=true] [data-button]{border-radius:4px;padding-left:8px;padding-right:8px;height:24px;font-size:12px;color:var(--normal-bg);background:var(--normal-text);margin-left:var(--toast-button-margin-start);margin-right:var(--toast-button-margin-end);border:none;font-weight:500;cursor:pointer;outline:0;display:flex;align-items:center;flex-shrink:0;transition:opacity .4s,box-shadow .2s}[data-sonner-toast][data-styled=true] [data-button]:focus-visible{box-shadow:0 0 0 2px rgba(0,0,0,.4)}[data-sonner-toast][data-styled=true] [data-button]:first-of-type{margin-left:var(--toast-button-margin-start);margin-right:var(--toast-button-margin-end)}[data-sonner-toast][data-styled=true] [data-cancel]{color:var(--normal-text);background:rgba(0,0,0,.08)}[data-sonner-toaster][data-sonner-theme=dark] [data-sonner-toast][data-styled=true] [data-cancel]{background:rgba(255,255,255,.3)}[data-sonner-toast][data-styled=true] [data-close-button]{position:absolute;left:var(--toast-close-button-start);right:var(--toast-close-button-end);top:0;height:20px;width:20px;display:flex;justify-content:center;align-items:center;padding:0;color:var(--gray12);background:var(--normal-bg);border:1px solid var(--gray4);transform:var(--toast-close-button-transform);border-radius:50%;cursor:pointer;z-index:1;transition:opacity .1s,background .2s,border-color .2s}[data-sonner-toast][data-styled=true] [data-close-button]:focus-visible{box-shadow:0 4px 12px rgba(0,0,0,.1),0 0 0 2px rgba(0,0,0,.2)}[data-sonner-toast][data-styled=true] [data-disabled=true]{cursor:not-allowed}[data-sonner-toast][data-styled=true]:hover [data-close-button]:hover{background:var(--gray2);border-color:var(--gray5)}[data-sonner-toast][data-swiping=true]::before{content:'';position:absolute;left:-100%;right:-100%;height:100%;z-index:-1}[data-sonner-toast][data-y-position=top][data-swiping=true]::before{bottom:50%;transform:scaleY(3) translateY(50%)}[data-sonner-toast][data-y-position=bottom][data-swiping=true]::before{top:50%;transform:scaleY(3) translateY(-50%)}[data-sonner-toast][data-swiping=false][data-removed=true]::before{content:'';position:absolute;inset:0;transform:scaleY(2)}[data-sonner-toast][data-expanded=true]::after{content:'';position:absolute;left:0;height:calc(var(--gap) + 1px);bottom:100%;width:100%}[data-sonner-toast][data-mounted=true]{--y:translateY(0);opacity:1}[data-sonner-toast][data-expanded=false][data-front=false]{--scale:var(--toasts-before) * 0.05 + 1;--y:translateY(calc(var(--lift-amount) * var(--toasts-before))) scale(calc(-1 * var(--scale)));height:var(--front-toast-height)}[data-sonner-toast]>*{transition:opacity .4s}[data-sonner-toast][data-x-position=right]{right:0}[data-sonner-toast][data-x-position=left]{left:0}[data-sonner-toast][data-expanded=false][data-front=false][data-styled=true]>*{opacity:0}[data-sonner-toast][data-visible=false]{opacity:0;pointer-events:none}[data-sonner-toast][data-mounted=true][data-expanded=true]{--y:translateY(calc(var(--lift) * var(--offset)));height:var(--initial-height)}[data-sonner-toast][data-removed=true][data-front=true][data-swipe-out=false]{--y:translateY(calc(var(--lift) * -100%));opacity:0}[data-sonner-toast][data-removed=true][data-front=false][data-swipe-out=false][data-expanded=true]{--y:translateY(calc(var(--lift) * var(--offset) + var(--lift) * -100%));opacity:0}[data-sonner-toast][data-removed=true][data-front=false][data-swipe-out=false][data-expanded=false]{--y:translateY(40%);opacity:0;transition:transform .5s,opacity .2s}[data-sonner-toast][data-removed=true][data-front=false]::before{height:calc(var(--initial-height) + 20%)}[data-sonner-toast][data-swiping=true]{transform:var(--y) translateY(var(--swipe-amount-y,0)) translateX(var(--swipe-amount-x,0));transition:none}[data-sonner-toast][data-swiped=true]{user-select:none}[data-sonner-toast][data-swipe-out=true][data-y-position=bottom],[data-sonner-toast][data-swipe-out=true][data-y-position=top]{animation-duration:.2s;animation-timing-function:ease-out;animation-fill-mode:forwards}[data-sonner-toast][data-swipe-out=true][data-swipe-direction=left]{animation-name:swipe-out-left}[data-sonner-toast][data-swipe-out=true][data-swipe-direction=right]{animation-name:swipe-out-right}[data-sonner-toast][data-swipe-out=true][data-swipe-direction=up]{animation-name:swipe-out-up}[data-sonner-toast][data-swipe-out=true][data-swipe-direction=down]{animation-name:swipe-out-down}@keyframes swipe-out-left{from{transform:var(--y) translateX(var(--swipe-amount-x));opacity:1}to{transform:var(--y) translateX(calc(var(--swipe-amount-x) - 100%));opacity:0}}@keyframes swipe-out-right{from{transform:var(--y) translateX(var(--swipe-amount-x));opacity:1}to{transform:var(--y) translateX(calc(var(--swipe-amount-x) + 100%));opacity:0}}@keyframes swipe-out-up{from{transform:var(--y) translateY(var(--swipe-amount-y));opacity:1}to{transform:var(--y) translateY(calc(var(--swipe-amount-y) - 100%));opacity:0}}@keyframes swipe-out-down{from{transform:var(--y) translateY(var(--swipe-amount-y));opacity:1}to{transform:var(--y) translateY(calc(var(--swipe-amount-y) + 100%));opacity:0}}@media (max-width:600px){[data-sonner-toaster]{position:fixed;right:var(--mobile-offset-right);left:var(--mobile-offset-left);width:100%}[data-sonner-toaster][dir=rtl]{left:calc(var(--mobile-offset-left) * -1)}[data-sonner-toaster] [data-sonner-toast]{left:0;right:0;width:calc(100% - var(--mobile-offset-left) * 2)}[data-sonner-toaster][data-x-position=left]{left:var(--mobile-offset-left)}[data-sonner-toaster][data-y-position=bottom]{bottom:var(--mobile-offset-bottom)}[data-sonner-toaster][data-y-position=top]{top:var(--mobile-offset-top)}[data-sonner-toaster][data-x-position=center]{left:var(--mobile-offset-left);right:var(--mobile-offset-right);transform:none}}[data-sonner-toaster][data-sonner-theme=light]{--normal-bg:#fff;--normal-border:var(--gray4);--normal-text:var(--gray12);--success-bg:hsl(143, 85%, 96%);--success-border:hsl(145, 92%, 87%);--success-text:hsl(140, 100%, 27%);--info-bg:hsl(208, 100%, 97%);--info-border:hsl(221, 91%, 93%);--info-text:hsl(210, 92%, 45%);--warning-bg:hsl(49, 100%, 97%);--warning-border:hsl(49, 91%, 84%);--warning-text:hsl(31, 92%, 45%);--error-bg:hsl(359, 100%, 97%);--error-border:hsl(359, 100%, 94%);--error-text:hsl(360, 100%, 45%)}[data-sonner-toaster][data-sonner-theme=light] [data-sonner-toast][data-invert=true]{--normal-bg:#000;--normal-border:hsl(0, 0%, 20%);--normal-text:var(--gray1)}[data-sonner-toaster][data-sonner-theme=dark] [data-sonner-toast][data-invert=true]{--normal-bg:#fff;--normal-border:var(--gray3);--normal-text:var(--gray12)}[data-sonner-toaster][data-sonner-theme=dark]{--normal-bg:#000;--normal-bg-hover:hsl(0, 0%, 12%);--normal-border:hsl(0, 0%, 20%);--normal-border-hover:hsl(0, 0%, 25%);--normal-text:var(--gray1);--success-bg:hsl(150, 100%, 6%);--success-border:hsl(147, 100%, 12%);--success-text:hsl(150, 86%, 65%);--info-bg:hsl(215, 100%, 6%);--info-border:hsl(223, 43%, 17%);--info-text:hsl(216, 87%, 65%);--warning-bg:hsl(64, 100%, 6%);--warning-border:hsl(60, 100%, 9%);--warning-text:hsl(46, 87%, 65%);--error-bg:hsl(358, 76%, 10%);--error-border:hsl(357, 89%, 16%);--error-text:hsl(358, 100%, 81%)}[data-sonner-toaster][data-sonner-theme=dark] [data-sonner-toast] [data-close-button]{background:var(--normal-bg);border-color:var(--normal-border);color:var(--normal-text)}[data-sonner-toaster][data-sonner-theme=dark] [data-sonner-toast] [data-close-button]:hover{background:var(--normal-bg-hover);border-color:var(--normal-border-hover)}[data-rich-colors=true][data-sonner-toast][data-type=success]{background:var(--success-bg);border-color:var(--success-border);color:var(--success-text)}[data-rich-colors=true][data-sonner-toast][data-type=success] [data-close-button]{background:var(--success-bg);border-color:var(--success-border);color:var(--success-text)}[data-rich-colors=true][data-sonner-toast][data-type=info]{background:var(--info-bg);border-color:var(--info-border);color:var(--info-text)}[data-rich-colors=true][data-sonner-toast][data-type=info] [data-close-button]{background:var(--info-bg);border-color:var(--info-border);color:var(--info-text)}[data-rich-colors=true][data-sonner-toast][data-type=warning]{background:var(--warning-bg);border-color:var(--warning-border);color:var(--warning-text)}[data-rich-colors=true][data-sonner-toast][data-type=warning] [data-close-button]{background:var(--warning-bg);border-color:var(--warning-border);color:var(--warning-text)}[data-rich-colors=true][data-sonner-toast][data-type=error]{background:var(--error-bg);border-color:var(--error-border);color:var(--error-text)}[data-rich-colors=true][data-sonner-toast][data-type=error] [data-close-button]{background:var(--error-bg);border-color:var(--error-border);color:var(--error-text)}.sonner-loading-wrapper{--size:16px;height:var(--size);width:var(--size);position:absolute;inset:0;z-index:10}.sonner-loading-wrapper[data-visible=false]{transform-origin:center;animation:sonner-fade-out .2s ease forwards}.sonner-spinner{position:relative;top:50%;left:50%;height:var(--size);width:var(--size)}.sonner-loading-bar{animation:sonner-spin 1.2s linear infinite;background:var(--gray11);border-radius:6px;height:8%;left:-10%;position:absolute;top:-3.9%;width:24%}.sonner-loading-bar:first-child{animation-delay:-1.2s;transform:rotate(.0001deg) translate(146%)}.sonner-loading-bar:nth-child(2){animation-delay:-1.1s;transform:rotate(30deg) translate(146%)}.sonner-loading-bar:nth-child(3){animation-delay:-1s;transform:rotate(60deg) translate(146%)}.sonner-loading-bar:nth-child(4){animation-delay:-.9s;transform:rotate(90deg) translate(146%)}.sonner-loading-bar:nth-child(5){animation-delay:-.8s;transform:rotate(120deg) translate(146%)}.sonner-loading-bar:nth-child(6){animation-delay:-.7s;transform:rotate(150deg) translate(146%)}.sonner-loading-bar:nth-child(7){animation-delay:-.6s;transform:rotate(180deg) translate(146%)}.sonner-loading-bar:nth-child(8){animation-delay:-.5s;transform:rotate(210deg) translate(146%)}.sonner-loading-bar:nth-child(9){animation-delay:-.4s;transform:rotate(240deg) translate(146%)}.sonner-loading-bar:nth-child(10){animation-delay:-.3s;transform:rotate(270deg) translate(146%)}.sonner-loading-bar:nth-child(11){animation-delay:-.2s;transform:rotate(300deg) translate(146%)}.sonner-loading-bar:nth-child(12){animation-delay:-.1s;transform:rotate(330deg) translate(146%)}@keyframes sonner-fade-in{0%{opacity:0;transform:scale(.8)}100%{opacity:1;transform:scale(1)}}@keyframes sonner-fade-out{0%{opacity:1;transform:scale(1)}100%{opacity:0;transform:scale(.8)}}@keyframes sonner-spin{0%{opacity:1}100%{opacity:.15}}@media (prefers-reduced-motion){.sonner-loading-bar,[data-sonner-toast],[data-sonner-toast]>*{transition:none!important;animation:none!important}}.sonner-loader{position:absolute;top:50%;left:50%;transform:translate(-50%,-50%);transform-origin:center;transition:opacity .2s,transform .2s}.sonner-loader[data-visible=false]{opacity:0;transform:scale(.8) translate(-50%,-50%)}
496</style><link rel="modulepreload" as="script" crossorigin="" href="/assets/StandaloneProductsPage-DQ6YTD3c.js"><link rel="modulepreload" as="script" crossorigin="" href="/assets/WalletPassesMockup-J1MQKBeh.js"><link rel="modulepreload" as="script" crossorigin="" href="/assets/products-CgyaoAcH.js"><link rel="modulepreload" as="script" crossorigin="" href="/assets/showcaseOrders-BnFVMJjS.js"><link rel="modulepreload" as="script" crossorigin="" href="/assets/bistroDemoContent-CxogUD1u.js"><link rel="modulepreload" as="script" crossorigin="" href="/assets/bistroDemoSelection-o4Yb_kvB.js"><link rel="modulepreload" as="script" crossorigin="" href="/assets/showcaseProductFixtures-KfSsHk09.js"><link rel="modulepreload" as="script" crossorigin="" href="/assets/giftLoyaltyDemoData-C1aEOjHE.js"><link rel="modulepreload" as="script" crossorigin="" href="/assets/marketingDemoData-27soL49f.js"><link rel="modulepreload" as="script" crossorigin="" href="/assets/signupBillModel-DagAgRmI.js"><link rel="modulepreload" as="script" crossorigin="" href="/assets/productAvailability-C7VIQZKa.js"><link rel="modulepreload" as="script" crossorigin="" href="/assets/giftCards-WoIDHPMC.js"><link rel="modulepreload" as="script" crossorigin="" href="/assets/WalletPass-Bz9FZh1e.js"><link rel="stylesheet" crossorigin="" href="/assets/wallet-pass-B5YePPVI.css"><link rel="modulepreload" as="script" crossorigin="" href="/assets/websiteFonts--jmrFa6j.js"><link rel="modulepreload" as="script" crossorigin="" href="/assets/websiteConfig-JjcOJiNk.js"><link rel="modulepreload" as="script" crossorigin="" href="/assets/orderAndPay-IvZhPpIU.js"><link rel="modulepreload" as="script" crossorigin="" href="/assets/productCtaIntent-DLxTYjSg.js"><link rel="stylesheet" crossorigin="" href="/assets/cookieconsent-zZa9xLX1.css"><link rel="stylesheet" crossorigin="" href="/assets/cookieConsent-DKOokvVu.css"><meta name="description" content="Gift cards, loyalty, tickets, Order & Pay, a website and your own domain â each works on its own, no booking system needed. From £7 a month."><meta property="og:title" content="Standalone products â for any business | ResoFlow"><meta property="og:description" content="Gift cards, loyalty, tickets, Order & Pay, a website and your own domain â each works on its own, no booking system needed. From £7 a month."><meta property="og:url" content="https://resoflow.co.uk/pricing/products"><meta property="og:image" content="https://resoflow.co.uk/og/og-pricing-products.png"><meta name="twitter:card" content="summary_large_image"><meta name="twitter:image" content="https://resoflow.co.uk/og/og-pricing-products.png"><meta property="og:image:alt" content="Standalone products â for any business | ResoFlow"><meta name="twitter:image:alt" content="Standalone products â for any business | ResoFlow"><link rel="canonical" href="https://resoflow.co.uk/pricing/products"></head> 497 <body> 498 <div id="root">
498<script nonce="">((e,t,n,a,r,s,o,i)=>{let l=document.documentElement,c=["light","dark"];function d(t){(Array.isArray(e)?e:[e]).forEach(e=>{let n="class"===e,a=n&&s?r.map(e=>s[e]||e):r;n?(l.classList.remove(...a),l.classList.add(s&&s[t]?s[t]:t)):l.setAttribute(e,t)}),function(e){i&&c.includes(e)&&(l.style.colorScheme=e)}(t)}if(a)d(a);else try{let e=localStorage.getItem(t)||n;d(o&&"system"===e?window.matchMedia("(prefers-color-scheme: dark)").matches?"dark":"light":e)}catch(u){}})("class","theme","light",null,["light","dark"],null,true,true)</script>
498<div class="rfsite mode-medium"><a href="#main-content" class="sr-only focus:not-sr-only focus:absolute focus:top-4 focus:left-4 focus:z-[300] focus:rounded-xl focus:bg-white focus:px-4 focus:py-2 focus:text-sm focus:font-bold focus:text-slate-900 focus:shadow-xl focus:ring-2 focus:ring-pink-500 no-underline">Skip to content</a><header class="sitenav" id="sitenav"><div class="wrap sitenav__in"><a class="sitenav__logo" aria-label="ResoFlow home" href="/" data-discover="true"><img alt="ResoFlow" src="/brand/resoflow-lockup-small.svg"></a><nav class="sitenav__links" aria-label="Main"><div class="nav-dd" data-dd=""><button class="navitem" data-dd-btn="" type="button" aria-expanded="false" aria-haspopup="true" aria-controls="dd-products">Products <span class="navitem__caret" aria-hidden="true"></span></button><div class="nav-dd__panel nav-dd__panel--mega" id="dd-products"><div><p class="nav-dd__grouplabel">For your industry</p><a class="nav-dd__item" href="/features" data-discover="true"><span class="nav-dd__icon" aria-hidden="true"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-utensils" aria-hidden="true" focusable="false"><path d="M3 2v7c0 1.1.9 2 2 2h4a2 2 0 0 0 2-2V2"></path><path d="M7 2v20"></path><path d="M21 15V2a5 5 0 0 0-5 5v6c0 1.1.9 2 2 2h3Zm0 0v7"></path></svg></span><span><span class="nav-dd__label">Restaurants & cafés</span><span class="nav-dd__sub">Bookings and guest tools â live today</span></span></a><a class="nav-dd__item" href="/interest?industry=activity-venues" data-discover="true"><span class="nav-dd__icon" aria-hidden="true"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-calendar-clock" aria-hidden="true" focusable="false"><path d="M16 14v2.2l1.6 1"></path><path d="M16 2v4"></path><path d="M21 7.5V6a2 2 0 0 0-2-2H5a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h3.5"></path><path d="M3 10h5"></path><path d="M8 2v4"></path><circle cx="16" cy="16" r="6"></circle></svg></span><span><span class="nav-dd__label">Activities & attractions<!----> <span class="nav-dd__badge">Coming soon</span></span><span class="nav-dd__sub">Register interest â be first to know</span></span></a><a class="nav-dd__item" href="/interest?industry=salons" data-discover="true"><span class="nav-dd__icon" aria-hidden="true"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-scissors" aria-hidden="true" focusable="false"><circle cx="6" cy="6" r="3"></circle><path d="M8.12 8.12 12 12"></path><path d="M20 4 8.12 15.88"></path><circle cx="6" cy="18" r="3"></circle><path d="M14.8 14.8 20 20"></path></svg></span><span><span class="nav-dd__label">Salons & barbers<!----> <span class="nav-dd__badge">Coming soon</span></span><span class="nav-dd__sub">Register interest â be first to know</span></span></a><a class="nav-dd__item" href="/interest?industry=shops-retail" data-discover="true"><span class="nav-dd__icon" aria-hidden="true"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-store" aria-hidden="true" focusable="false"><path d="M15 21v-5a1 1 0 0 0-1-1h-4a1 1 0 0 0-1 1v5"></path><path d="M17.774 10.31a1.12 1.12 0 0 0-1.549 0 2.5 2.5 0 0 1-3.451 0 1.12 1.12 0 0 0-1.548 0 2.5 2.5 0 0 1-3.452 0 1.12 1.12 0 0 0-1.549 0 2.5 2.5 0 0 1-3.77-3.248l2.889-4.184A2 2 0 0 1 7 2h10a2 2 0 0 1 1.653.873l2.895 4.192a2.5 2.5 0 0 1-3.774 3.244"></path><path d="M4 10.95V19a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2v-8.05"></path></svg></span><span><span class="nav-dd__label">Shops & retail<!----> <span class="nav-dd__badge">Coming soon</span></span><span class="nav-dd__sub">Register interest â be first to know</span></span></a></div><div><p class="nav-dd__grouplabel">Products for any business</p><a class="nav-dd__item" href="/features/gift-cards" data-discover="true"><span class="nav-dd__icon" aria-hidden="true"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-gift" aria-hidden="true" focusable="false"><rect x="3" y="8" width="18" height="4" rx="1"></rect><path d="M12 8v13"></path><path d="M19 12v7a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2v-7"></path><path d="M7.5 8a2.5 2.5 0 0 1 0-5A4.8 8 0 0 1 12 8a4.8 8 0 0 1 4.5-5 2.5 2.5 0 0 1 0 5"></path></svg></span><span><span class="nav-dd__label">Gift cards</span><span class="nav-dd__sub">£25/month</span></span></a><a class="nav-dd__item" href="/features/events" data-discover="true"><span class="nav-dd__icon" aria-hidden="true"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-ticket" aria-hidden="true" focusable="false">
498<path d="M2 9a3 3 0 0 1 0 6v2a2 2 0 0 0 2 2h16a2 2 0 0 0 2-2v-2a3 3 0 0 1 0-6V7a2 2 0 0 0-2-2H4a2 2 0 0 0-2 2Z"></path><path d="M13 5v2"></path><path d="M13 17v2"></path><path d="M13 11v2"></path></svg></span><span><span class="nav-dd__label">Tickets</span><span class="nav-dd__sub">One event a month free · £25/month for unlimited</span></span></a><a class="nav-dd__item" href="/features/loyalty" data-discover="true"><span class="nav-dd__icon" aria-hidden="true"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-heart" aria-hidden="true" focusable="false"><path d="M2 9.5a5.5 5.5 0 0 1 9.591-3.676.56.56 0 0 0 .818 0A5.49 5.49 0 0 1 22 9.5c0 2.29-1.5 4-3 5.5l-5.492 5.313a2 2 0 0 1-3 .019L5 15c-1.5-1.5-3-3.2-3-5.5"></path></svg></span><span><span class="nav-dd__label">Loyalty</span><span class="nav-dd__sub">£25/month</span></span></a><a class="nav-dd__item" href="/features/order-and-pay" data-discover="true"><span class="nav-dd__icon" aria-hidden="true"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-qr-code" aria-hidden="true" focusable="false"><rect width="5" height="5" x="3" y="3" rx="1"></rect><rect width="5" height="5" x="16" y="3" rx="1"></rect><rect width="5" height="5" x="3" y="16" rx="1"></rect><path d="M21 16h-3a2 2 0 0 0-2 2v3"></path><path d="M21 21v.01"></path><path d="M12 7v3a2 2 0 0 1-2 2H7"></path><path d="M3 12h.01"></path><path d="M12 3h.01"></path><path d="M12 16v.01"></path><path d="M16 12h1"></path><path d="M21 12v.01"></path><path d="M12 21v-1"></path></svg></span><span><span class="nav-dd__label">Order & Pay</span><span class="nav-dd__sub">From £29/month · At the table, collection & delivery</span></span></a><a class="nav-dd__item" href="/features/website" data-discover="true"><span class="nav-dd__icon" aria-hidden="true"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-panels-top-left" aria-hidden="true" focusable="false"><rect width="18" height="18" x="3" y="3" rx="2"></rect><path d="M3 9h18"></path><path d="M9 21V9"></path></svg></span><span><span class="nav-dd__label">Your website</span><span class="nav-dd__sub">£15/month</span></span></a><a class="nav-dd__item" href="/features/your-own-domain" data-discover="true"><span class="nav-dd__icon" aria-hidden="true"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-link2 lucide-link-2" aria-hidden="true" focusable="false"><path d="M9 17H7A5 5 0 0 1 7 7h2"></path><path d="M15 7h2a5 5 0 1 1 0 10h-2"></path><line x1="8" x2="16" y1="12" y2="12"></line></svg></span><span><span class="nav-dd__label">Your domain</span><span class="nav-dd__sub">£7/month</span></span></a></div></div></div><div class="nav-dd" data-dd=""><button class="navitem is-active" data-dd-btn="" type="button" aria-expanded="false" aria-haspopup="true" aria-controls="dd-pricing">Pricing <span class="navitem__caret" aria-hidden="true"></span></button><div class="nav-dd__panel" id="dd-pricing"><a class="nav-dd__item" href="/pricing" data-discover="true"><span class="nav-dd__icon" aria-hidden="true"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-calendar-days" aria-hidden="true" focusable="false"><path d="M8 2v4"></path><path d="M16 2v4"></path><rect width="18" height="18" x="3" y="4" rx="2"></rect><path d="M3 10h18"></path><path d="M8 14h.01"></path><path d="M12 14h.01"></path><path d="M16 14h.01"></path><path d="M8 18h.01"></path><path d="M12 18h.01"></path><path d="M16 18h.01"></path></svg></span><span><span class="nav-dd__label">Venue plans</span><span class="nav-dd__sub">
498The full booking platform for restaurants, cafés & bars â free to £129/month</span></span></a><a class="nav-dd__item" href="/pricing/products" data-discover="true"><span class="nav-dd__icon" aria-hidden="true"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-layers" aria-hidden="true" focusable="false"><path d="M12.83 2.18a2 2 0 0 0-1.66 0L2.6 6.08a1 1 0 0 0 0 1.83l8.58 3.91a2 2 0 0 0 1.66 0l8.58-3.9a1 1 0 0 0 0-1.83z"></path><path d="M2 12a1 1 0 0 0 .58.91l8.6 3.91a2 2 0 0 0 1.65 0l8.58-3.9A1 1 0 0 0 22 12"></path><path d="M2 17a1 1 0 0 0 .58.91l8.6 3.91a2 2 0 0 0 1.65 0l8.58-3.9A1 1 0 0 0 22 17"></path></svg></span><span><span class="nav-dd__label">Standalone products</span><span class="nav-dd__sub">Gift cards, loyalty, tickets, websites & more â any business, from £7/month</span></span></a></div></div><a class="navitem" href="/demo" data-discover="true">Live demo</a><div class="nav-dd" data-dd=""><button class="navitem" data-dd-btn="" type="button" aria-expanded="false" aria-haspopup="true" aria-controls="dd-res">Resources <span class="navitem__caret" aria-hidden="true"></span></button><div class="nav-dd__panel" id="dd-res"><a class="nav-dd__item" href="/help" data-discover="true"><span class="nav-dd__icon" aria-hidden="true"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-life-buoy" aria-hidden="true" focusable="false"><circle cx="12" cy="12" r="10"></circle><path d="m4.93 4.93 4.24 4.24"></path><path d="m14.83 9.17 4.24-4.24"></path><path d="m14.83 14.83 4.24 4.24"></path><path d="m9.17 14.83-4.24 4.24"></path><circle cx="12" cy="12" r="4"></circle></svg></span><span><span class="nav-dd__label">Support</span><span class="nav-dd__sub">Guides, FAQs and talk to us</span></span></a><a class="nav-dd__item" href="/book-a-call" data-discover="true"><span class="nav-dd__icon" aria-hidden="true"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-phone" aria-hidden="true" focusable="false"><path d="M13.832 16.568a1 1 0 0 0 1.213-.303l.355-.465A2 2 0 0 1 17 15h3a2 2 0 0 1 2 2v3a2 2 0 0 1-2 2A18 18 0 0 1 2 4a2 2 0 0 1 2-2h3a2 2 0 0 1 2 2v3a2 2 0 0 1-.8 1.6l-.468.351a1 1 0 0 0-.292 1.233 14 14 0 0 0 6.392 6.384"></path></svg></span><span><span class="nav-dd__label">Book a call</span><span class="nav-dd__sub">A free 30-minute call with the founder</span></span></a><a class="nav-dd__item" href="/setup" data-discover="true"><span class="nav-dd__icon" aria-hidden="true"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-wrench" aria-hidden="true" focusable="false"><path d="M14.7 6.3a1 1 0 0 0 0 1.4l1.6 1.6a1 1 0 0 0 1.4 0l3.106-3.105c.32-.322.863-.22.983.218a6 6 0 0 1-8.259 7.057l-7.91 7.91a1 1 0 0 1-2.999-3l7.91-7.91a6 6 0 0 1 7.057-8.259c.438.12.54.662.219.984z"></path></svg></span><span><span class="nav-dd__label">Free venue setup</span><span class="nav-dd__sub">We set everything up for you</span></span></a><a class="nav-dd__item" href="/compare" data-discover="true"><span class="nav-dd__icon" aria-hidden="true"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-arrow-left-right" aria-hidden="true" focusable="false"><path d="M8 3 4 7l4 4"></path><path d="M4 7h16"></path><path d="m16 21 4-4-4-4"></path><path d="M20 17H4"></path></svg></span><span><span class="nav-dd__label">Switching guides</span><span class="nav-dd__sub">Compare booking systems</span></span></a><a class="nav-dd__item" href="/news" data-discover="true"><span class="nav-dd__icon" aria-hidden="true"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-newspaper" aria-hidden="true" focusable="false">
498<path d="M15 18h-5"></path><path d="M18 14h-8"></path><path d="M4 22h16a2 2 0 0 0 2-2V4a2 2 0 0 0-2-2H8a2 2 0 0 0-2 2v16a2 2 0 0 1-4 0v-9a2 2 0 0 1 2-2h2"></path><rect width="8" height="4" x="10" y="6" rx="1"></rect></svg></span><span><span class="nav-dd__label">News</span><span class="nav-dd__sub">Product updates and announcements</span></span></a><a class="nav-dd__item" href="/about" data-discover="true"><span class="nav-dd__icon" aria-hidden="true"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-info" aria-hidden="true" focusable="false"><circle cx="12" cy="12" r="10"></circle><path d="M12 16v-4"></path><path d="M12 8h.01"></path></svg></span><span><span class="nav-dd__label">About</span><span class="nav-dd__sub">Who we are and how we work</span></span></a><a class="nav-dd__item" href="/security" data-discover="true"><span class="nav-dd__icon" aria-hidden="true"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-shield-check" aria-hidden="true" focusable="false"><path d="M20 13c0 5-3.5 7.5-7.66 8.95a1 1 0 0 1-.67-.01C7.5 20.5 4 18 4 13V6a1 1 0 0 1 1-1c2 0 4.5-1.2 6.24-2.72a1.17 1.17 0 0 1 1.52 0C14.51 3.81 17 5 19 5a1 1 0 0 1 1 1z"></path><path d="m9 12 2 2 4-4"></path></svg></span><span><span class="nav-dd__label">Security & reliability</span><span class="nav-dd__sub">How your data is protected</span></span></a></div></div></nav><div class="sitenav__actions"><a class="btn btn--sm btn--white btn--nav-secondary" data-cta="nav_log_in" href="/login" data-discover="true">Log in</a><a class="btn btn--sm btn--primary" data-cta="nav_start_free" href="/onboarding" data-discover="true">Start free</a><button class="nav-burger" type="button" aria-label="Open menu" aria-expanded="false" aria-controls="nav-drawer" data-burger=""><span></span></button></div></div><div class="nav-drawer" id="nav-drawer" role="dialog" aria-modal="true" aria-label="Menu" tabindex="-1"><div class="btns"><a class="btn btn--primary btn--block" data-cta="drawer_start_free" href="/onboarding" data-discover="true">Start free</a><a class="btn btn--secondary btn--block" data-cta="drawer_log_in" href="/login" data-discover="true">Log in</a></div><div class="nav-drawer__group"><p class="nav-drawer__grouplabel">For your industry</p><a class="nav-drawer__row" href="/features" data-discover="true">Restaurants & cafés <span>Live â</span></a><a class="nav-drawer__row" href="/interest?industry=activity-venues" data-discover="true">Activities & attractions <span>Coming soon</span></a><a class="nav-drawer__row" href="/interest?industry=salons" data-discover="true">Salons & barbers <span>Coming soon</span></a><a class="nav-drawer__row" href="/interest?industry=shops-retail" data-discover="true">Shops & retail <span>Coming soon</span></a></div><div class="nav-drawer__group"><p class="nav-drawer__grouplabel">Products for any business</p><a class="nav-drawer__row" href="/features/gift-cards" data-discover="true">Gift cards <span>£25<!---->/month</span></a><a class="nav-drawer__row" href="/features/events" data-discover="true">Tickets <span>Free to start</span></a><a class="nav-drawer__row" href="/features/loyalty" data-discover="true">Loyalty <span>£25<!---->/month</span></a><a class="nav-drawer__row" href="/features/order-and-pay" data-discover="true">Order & Pay <span>From <!---->£29<!---->/month</span></a><a class="nav-drawer__row" href="/features/website" data-discover="true">Your website <span>£15<!---->/month</span></a><a class="nav-drawer__row" href="/features/your-own-domain" data-discover="true">Your domain <span>£7<!---->/month</span></a></div><div class="nav-drawer__group"><p class="nav-drawer__grouplabel">Explore</p><a class="nav-drawer__row" href="/pricing" data-discover="true">Pricing â venue plans <span aria-hidden="true">â</span></a><a class="nav-drawer__row" href="/pricing/products" data-discover="true">Pricing â standalone products <span aria-hidden="true">â</span></a><a class="nav-drawer__row" href="/demo" data-discover="true">Live demo <span aria-hidden="true">â</span></a><a class="nav-drawer__row" href="/help" data-discover="true">Support <span aria-hidden="true">â</span></a><a class="nav-drawer__row" href="/book-a-call" data-discover="true">Book a call <span aria-hidden="true">â</span></a><a class="nav-drawer__row" href="/setup" data-discover="true">Free venue setup <span aria-hidden="true">â</span></a><a class="nav-drawer__row" href="/compare" data-discover="true">Switching guides <span aria-hidden="true">â</span></a><a class="nav-drawer__row" href="/news" data-discover="true">News <span aria-hidden="true">â</span></a><a class="nav-drawer__row" href="/about" data-discover="true">About <span aria-hidden="true">â</span></a><a class="nav-drawer__row" href="/security" data-discover="true">Security <span aria-hidden="true">â</span></a></div></div></header><main id="main-content"><header class="band band--pink"><div class="wrap section section--tight"><div class="grid-split"><div class="stack"><span class="eyebrow eyebrow--white">Pricing · standalone products</span><h1 class="rv">No booking system needed.<br><span class="hl-o">Pick a product, start today.</span></h1><p class="lede rv d1">Gift cards, loyalty, tickets, Order & Pay, a themed website and your own web address each work <b>completely on their own</b> â for florists, gyms, barbers, bakeries, theatres⦠any business at all. No venue plan required, cancel any time.</p><nav class="switch rv d2" aria-label="Pricing pages"><a class="switch__opt" href="/pricing">Venue plans</a><a class="switch__opt is-on" href="/pricing/products" aria-current="page">Standalone products</a></nav></div><div class="rv d2"><div class="frame"><div class="frame__head"><span class="frame__title">Six products, sold on their own</span><span class="frame__sub">6 to choose from</span></div><div class="frame__body" style="min-height: 232px;"><div class="stack stack--sm"><div class="row row--sm" role="group" aria-label="Pick a product"><button type="button" class="btn btn--sm btn--white" aria-pressed="false">Gift cards</button><button type="button" class="btn btn--sm btn--white" aria-pressed="false">Loyalty</button><button type="button" class="btn btn--sm btn--white" aria-pressed="false">Tickets</button><button type="button" class="btn btn--sm btn--white" aria-pressed="false">Order & Pay</button><button type="button" class="btn btn--sm btn--white" aria-pressed="false">Your website</button><button type="button" class="btn btn--sm btn--ink" aria-pressed="true">Your domain</button></div><div class="ui-board"><div class="ui-row"><span class="ui-name">
498No booking plan needed<small>Any plan, or none</small></span></div><div class="ui-row"><span class="ui-name">One bill<small>Plans and products share one subscription</small></span></div></div><div class="leaders"><div class="leader leader--lg"><span class="leader__label">Your domain</span><span class="leader__dots" aria-hidden="true"></span><span class="leader__value leader__value--ink">£7/month</span></div><div class="leader"><span class="leader__label">Pay annually</span><span class="leader__dots" aria-hidden="true"></span><span class="leader__value">£70 a year â two months free</span></div><div class="leader leader--ghost"><span class="leader__label"> </span><span class="leader__dots" aria-hidden="true"></span><span class="leader__value"> </span></div><div class="leader leader--ghost"><span class="leader__label"> </span><span class="leader__dots" aria-hidden="true"></span><span class="leader__value"> </span></div></div></div></div><div class="frame__foot"><span>No booking plan needed</span><span class="u-pink">Cancel any time</span></div></div></div></div></div></header><div class="marquee marquee--paper"><div class="marquee__track" aria-hidden="true"><span>Sold on its own</span><span class="marquee__star">â
</span><span>Features to suit your business</span><span class="marquee__star">â
</span><span>No booking platform attached</span><span class="marquee__star">â
</span><span>Cancel any time</span><span class="marquee__star">â
</span><span>Any business</span><span class="marquee__star">â
</span></div></div><section class="section"><div class="wrap stack stack--lg"><div class="row row--between row--baseline"><div class="sechead rv"><span class="eyebrow">Six products</span><h2>Six things you can buy.<br><span class="hl-p">One at a time, if you like.</span></h2></div><div class="switch rv d1" id="billing-switch" role="group" aria-label="Billing period"><button class="switch__opt is-on" type="button" aria-pressed="true">Monthly</button><button class="switch__opt" type="button" aria-pressed="false">Annual · 2 months free</button></div></div><div class="grid-3 rv d1"><div class="ticket ticket--hover"><span class="ticket__flag">No platform fee</span><div class="ticket__head"><span class="ticket__name">Gift cards</span><span class="ticket__name ticket__name--accent">01</span></div><div class="ticket__price"><span>£25</span><span class="ticket__per">/month</span></div><p class="ticket__desc"><span>Or £250 a year â two months free.</span><br>Sell from your own page and at the venue through your Stripe account. No ResoFlow sales fee; Stripe processing fees apply.</p><ul class="ticket__list plan__feats"><li>Occasion designs & scheduled delivery</li><li>Apple & Google Wallet passes with a live balance</li><li>Partial redemption â the rest stays on the card</li><li>A wall screen that sells them for you</li></ul><div class="ticket__perf"></div><div class="ticket__stub"><span class="ticket__stubnote">No platform fee</span><a class="btn btn--sm btn--ink btn--block" data-cta="body_start_selling_gift_cards" href="/onboarding?products=gift_cards_plus">Start selling gift cards</a></div></div><div class="ticket ticket--hover"><div class="ticket__head"><span class="ticket__name">Loyalty</span><span class="ticket__name ticket__name--accent">02</span></div><div class="ticket__price"><span>£25</span><span class="ticket__per">/month</span></div><p class="ticket__desc"><span>Or £250 a year â two months free.</span><br>Stamps or points, rewards written in your own words, and a card that lives in your customers' phone wallet. They join free.</p><ul class="ticket__list plan__feats"><li>Rewards & birthday gifts</li><li>Wallet cards that update live</li><li>Member portal for your customers</li><li>A join-our-scheme wall screen</li></ul><div class="ticket__perf"></div><div class="ticket__stub"><span class="ticket__stubnote">Customers join free</span><a class="btn btn--sm btn--ink btn--block" data-cta="body_start_a_loyalty_scheme" href="/onboarding?products=loyalty_plus">Start a loyalty scheme</a></div></div><div class="ticket ticket--hover"><span class="ticket__flag">Free to start</span><div class="ticket__head"><span class="ticket__name">Tickets</span><span class="ticket__name ticket__name--accent">03</span></div><div class="ticket__price"><span data-price="true">Free</span><span class="ticket__per" data-per="true" data-m=" to start" data-y=" to start"> to start</span></div><p class="ticket__desc"><span>One published event a month, free. £25 a month lifts the limit.</span><br>Sell tickets to your biggest nights, paid up front through Stripe.</p><ul class="ticket__list plan__feats"><li>Tiered pricing & capacity</li><li>QR check-in at the door</li><li>Money goes straight to your own Stripe account</li><li>Whatâs-on wall screen & event door display â with the paid tier</li></ul><div class="ticket__perf"></div><div class="ticket__stub"><span class="ticket__stubnote">2.9% + 50p<!----> a paid ticket</span><a class="btn btn--sm btn--ink btn--block" data-cta="body_start_selling_tickets" href="/onboarding?products=tickets_free">Start selling tickets</a></div></div><div class="ticket ticket--hover"><span class="ticket__flag">No app to download</span><div class="ticket__head"><span class="ticket__name">Order & Pay</span><span class="ticket__name ticket__name--accent">04</span></div><div class="ticket__price"><span>From <!---->£29</span><span class="ticket__per">/month</span></div><p class="ticket__desc"><span>Order & Pay Plus £29 a month â at the table. Order & Pay Pro £39 a month â adds collection & delivery.</span><br>Guests scan the table QR, browse your menu and pay from their own phone. Orders ring through to a live Orders screen for your team.</p><ul class="ticket__list plan__feats"><li>Table QR codes & a live Orders screen</li><li>Apple Pay & Google Pay</li><li>In-app refunds, whole order or single items</li><li>Kitchen & bar pass wall screens</li><li>Collection & delivery ordering â with Order & Pay Pro</li></ul><div class="ticket__perf"></div><div class="ticket__stub"><span class="ticket__stubnote">15p<!----> a paid table order · <!---->50p + 1%<!---->
498 a collection or delivery order</span><a class="btn btn--sm btn--ink btn--block" data-cta="body_start_taking_orders" href="/onboarding?products=order_pay_plus">Start taking orders</a></div></div><div class="ticket ticket--hover"><div class="ticket__head"><span class="ticket__name">Your website</span><span class="ticket__name ticket__name--accent">05</span></div><div class="ticket__price"><span>£15</span><span class="ticket__per">/month</span></div><p class="ticket__desc"><span>Or £150 a year â two months free.</span><br>A professional themed site, hosted and served by ResoFlow with HTTPS included. Choose a look, add your details and publish.</p><ul class="ticket__list plan__feats"><li>Ten professional looks tuned to your brand colour</li><li>Menu management included â build it in your dashboard</li><li>Menu, events and hours stay in step automatically</li><li>Switch pages on and off, no drag-and-drop needed</li><li>Menu wall screens included</li></ul><div class="ticket__perf"></div><div class="ticket__stub"><span class="ticket__stubnote">Hosting included</span><a class="btn btn--sm btn--ink btn--block" data-cta="body_build_your_website" href="/onboarding?products=website">Build your website</a></div></div><div class="ticket ticket--hover"><div class="ticket__head"><span class="ticket__name">Your domain</span><span class="ticket__name ticket__name--accent">06</span></div><div class="ticket__price"><span>£7</span><span class="ticket__per">/month</span></div><p class="ticket__desc"><span>Or £70 a year â two months free.</span><br>Connect the domain you already own. You paste one record; we check it, connect it and watch it every day after.</p><ul class="ticket__list plan__feats"><li>Your address serves your venue page â paste one record</li><li>Guest emails send from your domain once verified</li><li>Certificate issued and renewed automatically</li></ul><div class="ticket__perf"></div><div class="ticket__stub"><span class="ticket__stubnote">You keep your registrar</span><a class="btn btn--sm btn--ink btn--block" data-cta="body_connect_your_domain" href="/onboarding?products=your_own_domain">Connect your domain</a></div></div></div><p class="small u-muted rv">Buying and renewing the domain stays with your registrar. Check their registration and renewal prices. Order & Pay <b>Pro</b> adds collection and delivery at <!---->50p + 1%<!----> per collection or delivery order (of the food and drink total, after any discount or reward; tips, delivery charges and card processing never included; cash orders carry the same fee, billed monthly).</p></div></section><section class="band band--cream section"><div class="wrap stack stack--lg"><div class="sechead rv"><span class="eyebrow">What one product actually gets you</span><h2>Your product.<br><span class="hl-p">Ready to use.</span></h2><p class="lede">Each product works independently. Here are the tools included with each one.</p></div><div class="grid-3 rv d1"><div class="note note--ok"><p class="note__title">Every £25-and-up product brings</p><p>Gift cards, loyalty, the paid Tickets tier and Order & Pay each bring customer profiles and visit history, CSV import and export, the marketing email composer, SMS, and <b>250 MB of image storage</b>. Each active product also includes a staff seat in addition to the owner; if your booking plan includes more seats, you keep that larger allowance. Extra storage is <!---->£2<!----> per GB a month if you ever need it.</p></div><div class="note note--info"><p class="note__title">Website, domain and free Tickets</p><p>Free Tickets includes one published event a calendar month and 50 MB of storage.<b>Your website</b> includes the themed site, menu management and 250 MB of storage.<b>Your domain</b> connects your address and your domain's guest email. Each includes a staff seat. The customer and marketing tools above come with Gift Cards, Loyalty, paid Tickets and Order & Pay.</p></div><div class="note note--pink"><p class="note__title">And they join up</p><p>Use them together: eligible loyalty members can earn on orders, and guests can use gift cards at checkout when your venue enables them.</p></div></div><div class="grid-2 rv"><div class="frame"><div class="frame__head"><span class="frame__title">What your customer ends up holding</span><span class="frame__sub">Apple & Google Wallet</span></div><div class="frame__body"><div class="row row--lg row--top row--center"><div style="width: 190px; flex: 0 0 auto;"><div class="rf-wp " role="img" aria-label="A £50 The Bistro gift card as a phone wallet pass â live balance and QR code" style="aspect-ratio: 300 / 332;"><div class="rf-wp-card" aria-hidden="true"><div class="rf-wp-head"><span class="rf-wp-venue"><span class="rf-wp-logo"><img alt="" aria-hidden="true" width="160" height="160" loading="lazy" decoding="async" class="rf-mock-logo " src="/marketing/demo-logo.png"></span><span class="rf-wp-vname">The Bistro</span></span><span class="rf-wp-type">Gift card</span></div><span class="rf-wp-strip"><span class="rf-mock-cover " aria-hidden="true"><picture><source srcset="/marketing/demo-cover.avif" type="image/avif"><source srcset="/marketing/demo-cover.webp" type="image/webp"><img alt="" width="1600" height="1067" loading="lazy" decoding="async" src="/marketing/demo-cover.jpg"></picture><span class="rf-mock-wash"></span></span></span><div class="rf-wp-main"><span class="rf-wp-field "><span class="rf-wp-label">Balance</span><span class="rf-wp-value rf-wp-v-num">£50.00</span></span><span class="rf-qr rf-wp-qr" aria-hidden="true" style="width: calc(var(--u) * 58);">
498<svg class="rf-qr-svg" viewBox="0 0 29 29" shape-rendering="crispEdges" focusable="false" aria-hidden="true"><path d="M0 0h7v1h-7zM8 0h1v1h-1zM13 0h3v1h-3zM18 0h1v1h-1zM20 0h1v1h-1zM22 0h7v1h-7zM0 1h1v1h-1zM6 1h1v1h-1zM9 1h3v1h-3zM15 1h1v1h-1zM17 1h2v1h-2zM20 1h1v1h-1zM22 1h1v1h-1zM28 1h1v1h-1zM0 2h1v1h-1zM2 2h3v1h-3zM6 2h1v1h-1zM8 2h1v1h-1zM12 2h2v1h-2zM17 2h1v1h-1zM20 2h1v1h-1zM22 2h1v1h-1zM24 2h3v1h-3zM28 2h1v1h-1zM0 3h1v1h-1zM2 3h3v1h-3zM6 3h1v1h-1zM9 3h1v1h-1zM11 3h2v1h-2zM15 3h5v1h-5zM22 3h1v1h-1zM24 3h3v1h-3zM28 3h1v1h-1zM0 4h1v1h-1zM2 4h3v1h-3zM6 4h1v1h-1zM11 4h1v1h-1zM15 4h4v1h-4zM22 4h1v1h-1zM24 4h3v1h-3zM28 4h1v1h-1zM0 5h1v1h-1zM6 5h1v1h-1zM8 5h1v1h-1zM10 5h1v1h-1zM13 5h2v1h-2zM16 5h1v1h-1zM18 5h1v1h-1zM20 5h1v1h-1zM22 5h1v1h-1zM28 5h1v1h-1zM0 6h7v1h-7zM8 6h1v1h-1zM10 6h1v1h-1zM12 6h1v1h-1zM14 6h1v1h-1zM16 6h1v1h-1zM18 6h1v1h-1zM20 6h1v1h-1zM22 6h7v1h-7zM10 7h1v1h-1zM13 7h1v1h-1zM20 7h1v1h-1zM0 8h1v1h-1zM2 8h1v1h-1zM6 8h2v1h-2zM11 8h3v1h-3zM15 8h2v1h-2zM19 8h1v1h-1zM23 8h1v1h-1zM26 8h1v1h-1zM28 8h1v1h-1zM1 9h2v1h-2zM4 9h1v1h-1zM8 9h2v1h-2zM12 9h1v1h-1zM16 9h1v1h-1zM19 9h2v1h-2zM22 9h2v1h-2zM27 9h2v1h-2zM0 10h5v1h-5zM6 10h2v1h-2zM13 10h2v1h-2zM16 10h2v1h-2zM19 10h2v1h-2zM22 10h1v1h-1zM25 10h2v1h-2zM28 10h1v1h-1zM0 11h3v1h-3zM5 11h1v1h-1zM8 11h2v1h-2zM11 11h1v1h-1zM14 11h3v1h-3zM18 11h3v1h-3zM22 11h4v1h-4zM0 12h1v1h-1zM3 12h2v1h-2zM6 12h1v1h-1zM10 12h2v1h-2zM13 12h2v1h-2zM20 12h1v1h-1zM22 12h2v1h-2zM28 12h1v1h-1zM0 13h1v1h-1zM2 13h1v1h-1zM4 13h2v1h-2zM13 13h2v1h-2zM17 13h1v1h-1zM19 13h1v1h-1zM22 13h2v1h-2zM27 13h2v1h-2zM6 14h1v1h-1zM8 14h5v1h-5zM15 14h1v1h-1zM17 14h1v1h-1zM19 14h1v1h-1zM28 14h1v1h-1zM0 15h1v1h-1zM3 15h1v1h-1zM5 15h1v1h-1zM7 15h2v1h-2zM12 15h2v1h-2zM18 15h3v1h-3zM0 16h1v1h-1zM3 16h1v1h-1zM5 16h9v1h-9zM15 16h2v1h-2zM20 16h1v1h-1zM22 16h1v1h-1zM28 16h1v1h-1zM1 17h1v1h-1zM3 17h1v1h-1zM8 17h2v1h-2zM16 17h2v1h-2zM19 17h2v1h-2zM22 17h2v1h-2zM26 17h3v1h-3zM0 18h3v1h-3zM4 18h1v1h-1zM6 18h1v1h-1zM8 18h1v1h-1zM12 18h3v1h-3zM16 18h1v1h-1zM19 18h1v1h-1zM24 18h2v1h-2zM28 18h1v1h-1zM2 19h2v1h-2zM5 19h1v1h-1zM7 19h3v1h-3zM11 19h1v1h-1zM14 19h3v1h-3zM18 19h2v1h-2zM21 19h3v1h-3zM0 20h3v1h-3zM5 20h2v1h-2zM9 20h1v1h-1zM12 20h3v1h-3zM17 20h9v1h-9zM27 20h1v1h-1zM8 21h1v1h-1zM10 21h2v1h-2zM13 21h2v1h-2zM17 21h1v1h-1zM20 21h1v1h-1zM24 21h3v1h-3zM28 21h1v1h-1zM0 22h7v1h-7zM8 22h2v1h-2zM11 22h2v1h-2zM15 22h1v1h-1zM20 22h1v1h-1zM22 22h1v1h-1zM24 22h1v1h-1zM28 22h1v1h-1zM0 23h1v1h-1zM6 23h1v1h-1zM9 23h2v1h-2zM13 23h1v1h-1zM17 23h1v1h-1zM19 23h2v1h-2zM24 23h1v1h-1zM27 23h2v1h-2zM0 24h1v1h-1zM2 24h3v1h-3zM6 24h1v1h-1zM10 24h4v1h-4zM15 24h3v1h-3zM19 24h7v1h-7zM27 24h1v1h-1zM0 25h1v1h-1zM2 25h3v1h-3zM6 25h1v1h-1zM9 25h1v1h-1zM11 25h1v1h-1zM16 25h1v1h-1zM20 25h2v1h-2zM24 25h4v1h-4zM0 26h1v1h-1zM2 26h3v1h-3zM6 26h1v1h-1zM8 26h1v1h-1zM10 26h1v1h-1zM12 26h3v1h-3zM16 26h3v1h-3zM24 26h1v1h-1zM27 26h2v1h-2zM0 27h1v1h-1zM6 27h1v1h-1zM9 27h1v1h-1zM11 27h2v1h-2zM14 27h3v1h-3zM18 27h1v1h-1zM20 27h2v1h-2zM24 27h2v1h-2zM0 28h7v1h-7zM8 28h2v1h-2zM12 28h2v1h-2zM17 28h4v1h-4zM23 28h2v1h-2zM28 28h1v1h-1z" fill="#0f172a"></path></svg></span></div></div></div></div><div style="width: 190px; flex: 0 0 auto;"><div class="rf-wp " role="img" aria-label="The The Bistro Club loyalty card as a wallet pass â stamps earned and a QR code" style="aspect-ratio: 300 / 296;"><div class="rf-wp-card" aria-hidden="true"><div class="rf-wp-head"><span class="rf-wp-venue"><span class="rf-wp-logo"><img alt="" aria-hidden="true" width="160" height="160" loading="lazy" decoding="async" class="rf-mock-logo " src="/marketing/demo-logo.png"></span><span class="rf-wp-vname">The Bistro</span></span><span class="rf-wp-head-right"><span class="rf-wp-label">Stamps</span><span class="rf-wp-value rf-wp-v-num">7 of 10</span></span></div><div class="rf-wp-main"><span class="rf-wp-field "><span class="rf-wp-label">Member</span><span class="rf-wp-value ">Olivia Hartley</span></span><span class="rf-qr rf-wp-qr" aria-hidden="true" style="width: calc(var(--u) * 66);"><svg class="rf-qr-svg" viewBox="0 0 29 29" shape-rendering="crispEdges" focusable="false" aria-hidden="true"><path d="M0 0h7v1h-7zM8 0h1v1h-1zM13 0h3v1h-3zM18 0h1v1h-1zM20 0h1v1h-1zM22 0h7v1h-7zM0 1h1v1h-1zM6 1h1v1h-1zM9 1h3v1h-3zM15 1h1v1h-1zM17 1h2v1h-2zM20 1h1v1h-1zM22 1h1v1h-1zM28 1h1v1h-1zM0 2h1v1h-1zM2 2h3v1h-3zM6 2h1v1h-1zM8 2h1v1h-1zM12 2h2v1h-2zM17 2h1v1h-1zM20 2h1v1h-1zM22 2h1v1h-1zM24 2h3v1h-3zM28 2h1v1h-1zM0 3h1v1h-1zM2 3h3v1h-3zM6 3h1v1h-1zM9 3h1v1h-1zM11 3h2v1h-2zM15 3h5v1h-5zM22 3h1v1h-1zM24 3h3v1h-3zM28 3h1v1h-1zM0 4h1v1h-1zM2 4h3v1h-3zM6 4h1v1h-1zM11 4h1v1h-1zM15 4h4v1h-4zM22 4h1v1h-1zM24 4h3v1h-3zM28 4h1v1h-1zM0 5h1v1h-1zM6 5h1v1h-1zM8 5h1v1h-1zM10 5h1v1h-1zM13 5h2v1h-2zM16 5h1v1h-1zM18 5h1v1h-1zM20 5h1v1h-1zM22 5h1v1h-1zM28 5h1v1h-1zM0 6h7v1h-7zM8 6h1v1h-1zM10 6h1v1h-1zM12 6h1v1h-1zM14 6h1v1h-1zM16 6h1v1h-1zM18 6h1v1h-1zM20 6h1v1h-1zM22 6h7v1h-7zM10 7h1v1h-1zM13 7h1v1h-1zM20 7h1v1h-1zM0 8h1v1h-1zM2 8h1v1h-1zM6 8h2v1h-2zM11 8h3v1h-3zM15 8h2v1h-2zM19 8h1v1h-1zM23 8h1v1h-1zM26 8h1v1h-1zM28 8h1v1h-1zM1 9h2v1h-2zM4 9h1v1h-1zM8 9h2v1h-2zM12 9h1v1h-1zM16 9h1v1h-1zM19 9h2v1h-2zM22 9h2v1h-2zM27 9h2v1h-2zM0 10h5v1h-5zM6 10h2v1h-2zM13 10h2v1h-2zM16 10h2v1h-2zM19 10h2v1h-2zM22 10h1v1h-1zM25 10h2v1h-2zM28 10
498h1v1h-1zM0 11h3v1h-3zM5 11h1v1h-1zM8 11h2v1h-2zM11 11h1v1h-1zM14 11h3v1h-3zM18 11h3v1h-3zM22 11h4v1h-4zM0 12h1v1h-1zM3 12h2v1h-2zM6 12h1v1h-1zM10 12h2v1h-2zM13 12h2v1h-2zM20 12h1v1h-1zM22 12h2v1h-2zM28 12h1v1h-1zM0 13h1v1h-1zM2 13h1v1h-1zM4 13h2v1h-2zM13 13h2v1h-2zM17 13h1v1h-1zM19 13h1v1h-1zM22 13h2v1h-2zM27 13h2v1h-2zM6 14h1v1h-1zM8 14h5v1h-5zM15 14h1v1h-1zM17 14h1v1h-1zM19 14h1v1h-1zM28 14h1v1h-1zM0 15h1v1h-1zM3 15h1v1h-1zM5 15h1v1h-1zM7 15h2v1h-2zM12 15h2v1h-2zM18 15h3v1h-3zM0 16h1v1h-1zM3 16h1v1h-1zM5 16h9v1h-9zM15 16h2v1h-2zM20 16h1v1h-1zM22 16h1v1h-1zM28 16h1v1h-1zM1 17h1v1h-1zM3 17h1v1h-1zM8 17h2v1h-2zM16 17h2v1h-2zM19 17h2v1h-2zM22 17h2v1h-2zM26 17h3v1h-3zM0 18h3v1h-3zM4 18h1v1h-1zM6 18h1v1h-1zM8 18h1v1h-1zM12 18h3v1h-3zM16 18h1v1h-1zM19 18h1v1h-1zM24 18h2v1h-2zM28 18h1v1h-1zM2 19h2v1h-2zM5 19h1v1h-1zM7 19h3v1h-3zM11 19h1v1h-1zM14 19h3v1h-3zM18 19h2v1h-2zM21 19h3v1h-3zM0 20h3v1h-3zM5 20h2v1h-2zM9 20h1v1h-1zM12 20h3v1h-3zM17 20h9v1h-9zM27 20h1v1h-1zM8 21h1v1h-1zM10 21h2v1h-2zM13 21h2v1h-2zM17 21h1v1h-1zM20 21h1v1h-1zM24 21h3v1h-3zM28 21h1v1h-1zM0 22h7v1h-7zM8 22h2v1h-2zM11 22h2v1h-2zM15 22h1v1h-1zM20 22h1v1h-1zM22 22h1v1h-1zM24 22h1v1h-1zM28 22h1v1h-1zM0 23h1v1h-1zM6 23h1v1h-1zM9 23h2v1h-2zM13 23h1v1h-1zM17 23h1v1h-1zM19 23h2v1h-2zM24 23h1v1h-1zM27 23h2v1h-2zM0 24h1v1h-1zM2 24h3v1h-3zM6 24h1v1h-1zM10 24h4v1h-4zM15 24h3v1h-3zM19 24h7v1h-7zM27 24h1v1h-1zM0 25h1v1h-1zM2 25h3v1h-3zM6 25h1v1h-1zM9 25h1v1h-1zM11 25h1v1h-1zM16 25h1v1h-1zM20 25h2v1h-2zM24 25h4v1h-4zM0 26h1v1h-1zM2 26h3v1h-3zM6 26h1v1h-1zM8 26h1v1h-1zM10 26h1v1h-1zM12 26h3v1h-3zM16 26h3v1h-3zM24 26h1v1h-1zM27 26h2v1h-2zM0 27h1v1h-1zM6 27h1v1h-1zM9 27h1v1h-1zM11 27h2v1h-2zM14 27h3v1h-3zM18 27h1v1h-1zM20 27h2v1h-2zM24 27h2v1h-2zM0 28h7v1h-7zM8 28h2v1h-2zM12 28h2v1h-2zM17 28h4v1h-4zM23 28h2v1h-2zM28 28h1v1h-1z" fill="#0f172a"></path></svg></span></div></div></div></div></div><div class="leaders mt-4"><div class="leader ui-stage"><span class="leader__label">Checking a gift-card balance</span><span class="leader__dots" aria-hidden="true"></span><span class="leader__value leader__value--ink">Online, with just the code</span></div><div class="leader ui-stage"><span class="leader__label">Spending part of one</span><span class="leader__dots" aria-hidden="true"></span><span class="leader__value leader__value--ink">The rest stays on the card</span></div><div class="leader ui-stage"><span class="leader__label">Joining your loyalty scheme</span><span class="leader__dots" aria-hidden="true"></span><span class="leader__value leader__value--ink">Free, and takes an email</span></div><div class="leader ui-stage"><span class="leader__label">Printing a card as a certificate</span><span class="leader__dots" aria-hidden="true"></span><span class="leader__value leader__value--ink">Every gift card, any time</span></div></div></div><div class="frame__foot"><span>In your colours, not ours</span><span class="u-pink">Balances update live</span></div></div><div class="frame"><div class="frame__head"><span class="frame__title">And what your team sees</span><span class="live">Live</span></div><div class="frame__body row row--lg row--top row--center"><div class="ui-order u-fill" style="min-width: 230px;"><div class="ui-order__head"><span>Table 7 · #A118</span><small>Just now</small></div><div class="ui-order__lines"><div class="ui-line"><span class="ui-qty">2Ã</span><span class="u-fill">Beer-battered haddock & chips<small>one gluten-free</small></span></div><div class="ui-line"><span class="ui-qty">1Ã</span><span class="u-fill">Steak & ale pie<small>extra gravy</small></span></div><div class="ui-line"><span class="ui-qty">3Ã</span><span class="u-fill">Triple-cooked chips</span></div></div><div style="padding: 4px 12px 10px; display: flex; align-items: center; gap: 8px;"><span class="ui-btn ui-btn--accent" style="flex: 1 1 0%; text-align: center;">Start preparing</span></div><div class="ui-order__foot"><span>Paid in full · tip £5.95</span><span>£65.45</span></div></div><div class="ui-phone" style="width: 300px;"><div class="ui-phone__screen" style="min-height: 252px;"><div class="ui-phone__bar">Table 7 · Your order</div><div class="ui-phone__body"><div class="ui-board"><div class="ui-row"><span class="ui-name">Beer-battered haddock & chips<small>Ã2 · one gluten-free</small></span><span class="ui-chip">£31.00</span></div><div class="ui-row"><span class="ui-name">Steak & ale pie<small>Ã1 · extra gravy</small></span><span class="ui-chip">£15.00</span></div><div class="ui-row"><span class="ui-name">Triple-cooked chips<small>Ã3</small></span><span class="ui-chip">£13.50</span></div><div class="ui-row"><span class="ui-name">Tip<small>10% · optional</small></span><span class="ui-chip ui-chip--mint">£5.95</span></div></div><div class="u-fill"></div><span class="btn btn--sm btn--block ui-stage--lift" style="background: rgb(53, 41, 31); color: rgb(255, 255, 255); border-color: rgb(53, 41, 31);">Place order<!----> · <!---->£65.45</span></div></div></div></div><div class="frame__foot"><span>No app to download</span><span class="u-pink">Apple Pay & Google Pay</span></div></div></div></div></section><section class="section"><div class="wrap stack stack--lg"><div class="sechead rv"><span class="eyebrow">The money</span><h2>Your Stripe account.<br><span class="hl-p">Your money.</span></h2><p class="lede">Customer card payments go through your own Stripe account, with your business as merchant of record. Manage supported refunds in ResoFlow and follow their status. Some payments need further checking with Stripe.</p></div><div class="grid-2 rv d1"><div class="stack stack--sm"><h3 class="title-4">What ResoFlow charges on a sale</h3><div class="leaders"><div class="leader"><span class="leader__label">Gift card sales</span><span class="leader__dots"></span><span class="leader__value">£0 · Stripe processing applies</span></div><div class="leader"><span class="leader__label">Event tickets</span><span class="leader__dots"></span><span class="leader__value">2.9% + 50p<!----> a paid ticket</span></div><div class="leader"><span class="leader__label">Free & complimentary tickets</span><span class="leader__dots"></span><span class="leader__value">£0</span></div><div class="leader"><span class="leader__label">Order & Pay table orders</span><span class="leader__dots"></span><span class="leader__value">15p<!---->
498 a paid table order</span></div><div class="leader"><span class="leader__label">Collection & delivery orders</span><span class="leader__dots"></span><span class="leader__value">50p + 1%<!----> an order</span></div><div class="leader"><span class="leader__label">Orders fully covered by a gift card</span><span class="leader__dots"></span><span class="leader__value">£0</span></div><div class="leader"><span class="leader__label">Tips</span><span class="leader__dots"></span><span class="leader__value">Never touched</span></div><div class="leader"><span class="leader__label">Card processing</span><span class="leader__dots"></span><span class="leader__value">Stripe's standard rate</span></div></div><p class="tiny">The ticket fee is absorbed by your business by default, or passed to the guest and shown clearly before they pay. The table-order fee comes out of your payout â it is never added to the customer's bill. The collection and delivery fee is <!---->50p + 1%<!----> of the food and drink total (after any discount or reward; tips, delivery charges and card processing never included) â from your payout, or added to the customer's total if you choose; cash orders carry the same fee, billed monthly.</p></div><div class="stack stack--sm"><h3 class="title-4">And how the billing works</h3><div class="leaders"><div class="leader"><span class="leader__label">Billing</span><span class="leader__dots"></span><span class="leader__value leader__value--ink">Monthly, cancel any time</span></div><div class="leader"><span class="leader__label">Annual</span><span class="leader__dots"></span><span class="leader__value leader__value--ink">Ten months, not twelve</span></div><div class="leader"><span class="leader__label">Products + a venue plan</span><span class="leader__dots"></span><span class="leader__value leader__value--ink">One subscription per venue</span></div><div class="leader"><span class="leader__label">If a plan already includes it</span><span class="leader__dots"></span><span class="leader__value leader__value--ink">The charge comes off automatically</span></div><div class="leader"><span class="leader__label">Cancelling</span><span class="leader__dots"></span><span class="leader__value leader__value--ink">Cancel from your dashboard</span></div><div class="leader"><span class="leader__label">Extra image storage</span><span class="leader__dots"></span><span class="leader__value leader__value--ink">£2<!----> per GB a month</span></div><div class="leader"><span class="leader__label">SMS & email top-ups</span><span class="leader__dots"></span><span class="leader__value leader__value--ink">One-off packs, never expire</span></div></div><p class="tiny">Card payments run through your own Stripe account, so you are the merchant. Your bookings and guest records are stored in the EU, in Belgium. Other providers may process limited data elsewhere; see our <a class="link" href="/policies/subprocessors">sub-processors page</a> for locations and safeguards.</p></div></div></div></section><section class="band band--cream section"><div class="wrap stack stack--lg"><div class="sechead rv"><span class="eyebrow">Choosing your setup</span><h2>Sometimes a plan<br><span class="hl-p">is the better buy.</span></h2><p class="lede">Compare the features you need as well as the monthly price.</p></div><div class="steps rv d1"><div class="step"><span class="step__no">One product</span><h3 class="step__title">Buy the product</h3><p class="step__body">From <!---->£7<!----> a month, on its own, for any business. Choose the product that suits your business; features and public pages vary by product.</p></div><div class="step"><span class="step__no">Need bookings too?</span><h3 class="step__title">Do the sums</h3><p class="step__body">Pro at <!---->£79<!----> a month bundles gift cards, tickets and loyalty. Complete at <!---->£129<!----> adds Order & Pay. Compare the total for your chosen products with the plan and booking features you need.</p></div><div class="step"><span class="step__no">Either way</span><h3 class="step__title">The website stays its own thing</h3><p class="step__body">Your website (<!---->£15<!---->/month) and your domain (<!---->£7<!---->/month) are separate products on every plan, including Complete. Choose either or both as needed.</p></div></div><div class="btns rv"><a class="btn btn--primary" data-cta="body_compare_the_venue_plans" href="/pricing">Compare the venue plans</a><a class="btn btn--secondary" href="/pricing#choose" data-cta="products_compare_setup">Compare a plan with your products</a><a class="btn btn--secondary" data-cta="body_see_every_feature" href="/features">See every feature</a></div></div></section><section class="section"><div class="wrap stack stack--lg"><div class="sechead rv"><span class="eyebrow">Before you start</span><h2>Common questions.</h2></div><div class="faq rv d1"><details class="faq__item"><summary class="faq__q">Do I need to be a restaurant?</summary><div class="faq__a"><p>No. Each product is available separately, with no booking plan required â for florists, gyms, barbers, bakeries, theatres and other businesses. Choose the features you need; public pages vary by product, and Your domain connects your web address to your existing ResoFlow pages.</p><p>The full booking platform is live for restaurants and cafés today. Activities and attractions, salons and barbers, and shops and retail are on the way â you can register interest for those, and these products already work for you right now.</p></div></details>
498<details class="faq__item"><summary class="faq__q">Who actually takes the customer's payment?</summary><div class="faq__a"><p>You do. Payments go into your own Stripe account, so you are the merchant of record. ResoFlow never holds your money, and card numbers go straight to Stripe â we never store them.</p><p>You need a connected Stripe account to accept online card payments. Manage supported refunds in ResoFlow and follow their progress. Payments that need further checks stay visible for follow-up; some cases need attention with Stripe.</p></div></details><details class="faq__item"><summary class="faq__q">Can I have more than one?</summary><div class="faq__a"><p>Yes. Eligible loyalty members can earn on orders, and guests can use gift cards at checkout when your venue enables them. Each active product includes a staff seat in addition to the owner. If your booking plan includes more seats, you keep that larger allowance.</p><p>Your venue's plan and products sit on one subscription and one bill, and a product a plan already includes is never charged twice. A venue you add to an account keeps its own subscription on the account's card; a venue that joins an account by invitation is billed on that account's one invoice.</p></div></details><details class="faq__item"><summary class="faq__q">What if it turns out not to suit me?</summary><div class="faq__a"><p>Cancel from your dashboard; paid products stay active until the end of the period you have paid for. There is no separate cancellation fee, and any existing charges remain due. Choose monthly or annual billing, and use the available exports or ask support for a copy of your venue data before closing your account.</p><p>Add or remove any product whenever you like â one product today, three next spring, back to one after Christmas. Nothing about that is a renegotiation.</p></div></details></div></div></section><div class="band band--pink"><div class="wrap ctastrip"><h2>Pick a product.<br><span class="hl-o">Start today.</span></h2><p class="ctastrip__sub">Each one sets up on its own â no booking platform attached, cancel whenever you like.</p><div class="ctastrip__actions"><a class="btn btn--lg btn--yellow" data-cta="closing_start_free" href="/onboarding">Start free</a><a class="btn btn--lg btn--outline" data-cta="closing_try_live_demo" href="/demo">Try the live demo</a></div><p class="ctastrip__note">No credit card required · Free plan available · 14-day money-back guarantee on paid plans</p></div></div></main><footer class="sitefoot"><div class="wrap"><div class="sitefoot__grid"><div class="sitefoot__brand"><a aria-label="ResoFlow home" href="/" data-discover="true"><img alt="ResoFlow" src="/brand/resoflow-lockup-small.svg"></a><p class="sitefoot__blurb">Bookings, gift cards, tickets, loyalty and Order & Pay â one platform. Built in Scotland, UK company.</p><div class="sitefoot__social"><a href="https://www.instagram.com/resoflowUK" aria-label="ResoFlow on Instagram"><svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><rect x="2" y="2" width="20" height="20" rx="5"></rect><path d="M16 11.37A4 4 0 1 1 12.63 8 4 4 0 0 1 16 11.37z"></path><line x1="17.5" y1="6.5" x2="17.51" y2="6.5"></line></svg></a><a href="https://www.facebook.com/resoflow" aria-label="ResoFlow on Facebook"><svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><g transform="translate(-.5 0)"><path d="M18 2h-3a5 5 0 0 0-5 5v3H7v4h3v8h4v-8h3l1-4h-4V7a1 1 0 0 1 1-1h3z"></path></g></svg></a></div></div><div class="sitefoot__col"><p class="sitefoot__coltitle">Products</p><div class="sitefoot__links"><a href="/features" data-discover="true">Bookings</a><a href="/features/gift-cards" data-discover="true">Gift cards</a><a href="/features/events" data-discover="true">Tickets</a><a href="/features/loyalty" data-discover="true">Loyalty</a><a href="/features/order-and-pay" data-discover="true">Order & Pay</a><a href="/features/website" data-discover="true">Your website</a><a href="/features/your-own-domain" data-discover="true">Your domain</a><a href="/pricing" data-discover="true">Pricing</a><a href="/pricing/products" data-discover="true">Standalone products</a></div></div><div class="sitefoot__col"><p class="sitefoot__coltitle">Explore</p><div class="sitefoot__links"><a href="/demo" data-discover="true">Live demo</a><a href="/setup" data-discover="true">Free venue setup</a><a href="/compare" data-discover="true">Compare booking systems</a><a href="/integrations" data-discover="true">Integrations</a><a href="/news" data-discover="true">News</a><a href="/interest" data-discover="true">Register interest</a></div></div><div class="sitefoot__col"><p class="sitefoot__coltitle">Company</p><div class="sitefoot__links"><a href="/about" data-discover="true">About</a><a href="/help" data-discover="true">Support</a><a href="/book-a-call" data-discover="true">Book a call</a><a href="/security" data-discover="true">Security</a>
498<a href="https://status.resoflow.co.uk/">System status</a></div></div></div><div class="sitefoot__legal"><div>© <span>2026</span> ResoFlow · a trading name of Caleonix LTD · Company No. 17162652 · Registered in England & Wales · 71â75 Shelton Street, London WC2H 9JQ</div><div class="sitefoot__legalinks"><a href="/policies/terms" data-discover="true">Terms</a><a href="/policies/privacy" data-discover="true">Privacy</a><a href="/policies/cookies" data-discover="true">Cookies</a><a href="/policies/accessibility" data-discover="true">Accessibility</a><button type="button">Cookie preferences</button></div></div></div></footer><div class="rf-rezo-slot"></div></div><section aria-label="Notifications alt+T" tabindex="-1" aria-live="polite" aria-relevant="additions text" aria-atomic="false"></section></div> 499
499<script> 500 // L&R audit P3 (LR-11, 2026-07-10) â entry-splash watchdog. If the JS 501 // entry bundle itself 404s or stalls (stale HTML via a proxy that 502 // ignores no-store, a dropped connection mid-download), NOTHING else 503 // can recover: the chunk-error handler only installs after App mounts, 504 // so the page used to sit on the spinner forever ("airport: 5 reloads, 505 // nothing"). Plain DOM, no dependencies. React's mount replaces 506 // #root's children, so on every healthy load the splash is gone long 507 // before the timer fires and this is a no-op. 508 (function () { 509 var WATCHDOG_MS = 25000; 510 setTimeout(function () { 511 try { 512 var sp = document.getElementById('initial-splash'); 513 if (!sp) return; // app mounted (or prerendered page) â healthy 514 // Entry-funnel fix (2026-07-13): the 'onboarding' splash kind no 515 // longer exists (the funnel is light) â 'dark' is the only dark kind. 516 var splashKind = document.documentElement.getAttribute('data-splash'); 517 var dark = splashKind === 'dark'; 518 // Rule 5b (GUEST-TRUTH, 2026-09-11): on a venue's guest surface the 519 // button is the neutral, never ResoFlow's pink. 520 var guest = splashKind === 'guest'; 521 var spinner = sp.querySelector('.rf-sp'); 522 if (spinner) spinner.style.display = 'none'; 523 var box = document.createElement('div'); 524 box.style.cssText = 525 'max-width:420px;text-align:center;padding:0 24px;' + 526 'font-family:ui-sans-serif,system-ui,-apple-system,sans-serif;' + 527 'color:' + (dark ? '#E2E8F0' : '#0F172A'); 528 var h = document.createElement('p'); 529 h.textContent = 'This is taking longer than it shouldâ¦'; 530 h.style.cssText = 'margin:0 0 8px;font-size:16px;font-weight:600'; 531 var p = document.createElement('p'); 532 p.textContent = 'Your connection may be weak. Please reload to try again.'; 533 p.style.cssText = 'margin:0 0 20px;font-size:14px;color:' + (dark ? '#94A3B8' : '#64748B'); 534 var btn = document.createElement('button'); 535 btn.type = 'button'; 536 btn.textContent = 'Reload'; 537 btn.style.cssText = 538 'padding:10px 22px;border-radius:12px;border:0;cursor:pointer;' + 539 'font-size:14px;font-weight:600;color:#fff;background:' + (guest ? '#18181B' : '#BE185D'); 540 btn.onclick = function () { window.location.reload(); }; 541 box.appendChild(h); 542 box.appendChild(p); 543 box.appendChild(btn); 544 sp.appendChild(box); 545 } catch (e) { /* never break the page from a watchdog */ } 546 }, WATCHDOG_MS); 547 })(); 548 // @resoflow-sw-scrub-start 549 // Force-kill any STALE service workers and caches â the old PWA 550 // service worker (deleted 2026-05-07, CLAUDE.md gotcha #9) was 551 // intercepting requests and breaking the site. FA-R365 F14 (2026-09-04): 552 // the scrub is now SCOPED â it unregisters only FOREIGN registrations 553 // (any script that is not our push-only worker at /push-sw.js), because 554 // the unconditional version killed the push worker on every navigation. 555 // The cache purge stays unconditional: the push worker never writes a 556 // cache, so any cache on this origin is the old worker's. Logic twin + 557 // tripwire: src/utils/serviceWorkerPolicy.ts, 558 // tests/push-service-worker-survival.test.ts (keep the literal in step). 559 (function () { 560 var PUSH_SW_PATH = '/push-sw.js'; 561 function isForeignWorker(reg) { 562 var w = reg && (reg.active || reg.waiting || reg.installing); 563 var url = w && typeof w.scriptURL === 'string' ? w.scriptURL : ''; 564 if (!url) return true; 565 try { 566 var a = url.indexOf('//') === -1 ? url : url.slice(url.indexOf('//') + 2); 567 var slash = a.indexOf('/'); 568 var path = slash === -1 ? '/' : a.slice(slash); 569 var q = path.indexOf('?'); if (q !== -1) path = path.slice(0, q); 570 var h = path.indexOf('#'); if (h !== -1) path = path.slice(0, h); 571 return path !== PUSH_SW_PATH; 572 } catch (e) { return true; } 573 } 574 if ('serviceWorker' in navigator) { 575 navigator.serviceWorker.getRegistrations().then(function(regs) {
576 regs.forEach(function(r) { if (isForeignWorker(r)) r.unregister(); }); 577 }); 578 } 579 if ('caches' in window) { 580 caches.keys().then(function(names) { 581 names.forEach(function(n) { caches.delete(n); }); 582 }); 583 } 584 })(); 585 // @resoflow-sw-scrub-end 586 </script>
586 587 588 589</body></html>
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.