1<!doctype html> 2<html lang="en"> 3<head> 4<meta charset="utf-8"> 5<!-- Google Tag Manager â deferred until first user interaction -->
6<script>(function(w,d){w.dataLayer=w.dataLayer||[];var evts=['pointerdown','touchstart','wheel','keydown','click'],opts={once:true,passive:true,capture:true},done=false;function load(){if(done)return;done=true;evts.forEach(function(e){w.removeEventListener(e,load,opts)});w.dataLayer.push({'gtm.start':new Date().getTime(),event:'gtm.js'});var f=d.getElementsByTagName('script')[0],j=d.createElement('script');j.async=true;j.src='https://www.googletagmanager.com/gtm.js?id=GTM-5PRV2XG';f.parentNode.insertBefore(j,f)}evts.forEach(function(e){w.addEventListener(e,load,opts)})})(window,document);</script>
6 7<!-- End Google Tag Manager -->
8<script>(function(){try{var t=localStorage.getItem('infi-theme');if(t==='dark'||t==='light')document.documentElement.setAttribute('data-theme',t)}catch(e){}})();</script>
vendor: 1 bytes, line 8
8
9<script>(function(){try{if(matchMedia('(prefers-reduced-motion:reduce)').matches)return;if(!('IntersectionObserver'in window))return;var h=document.documentElement;h.className+=' lnr-arm';window.__lnrArm=setTimeout(function(){h.classList.remove('lnr-arm')},3500);}catch(e){}})();</script>
9 10<meta name="viewport" content="width=device-width, initial-scale=1"> 11<title>INFI News & Announcements â Restaurant Technology Updates</title> 12<meta name="description" content="The latest INFI news: funding, partnerships, trade shows and events, company milestones, and product announcements from across our restaurant self-ordering platform."> 13<meta name="robots" content="index, follow, max-image-preview:large, max-snippet:-1, max-video-preview:-1"> 14<link rel="canonical" href="https://infi.us/news"> 15<meta name="author" content="INFI"> 16<meta name="theme-color" content="#0a1230" media="(prefers-color-scheme: dark)"> 17<meta name="theme-color" content="#eef2fb" media="(prefers-color-scheme: light)"> 18<meta property="og:type" content="website"> 19<meta property="og:site_name" content="INFI"> 20<meta property="og:title" content="INFI News & Announcements â Restaurant Technology Updates"> 21<meta property="og:description" content="The latest INFI news: funding, partnerships, trade shows and events, company milestones, and product announcements from across our restaurant self-ordering platform."> 22<meta property="og:url" content="https://infi.us/news"> 23<meta property="og:image" content="https://infi.us/img/og/news.jpg?v=3"> 24<meta property="og:image:type" content="image/jpeg"> 25<meta property="og:image:width" content="1200"> 26<meta property="og:image:height" content="630"> 27<meta property="og:locale" content="en_US"> 28<meta name="twitter:card" content="summary_large_image"> 29<meta name="twitter:title" content="INFI News & Announcements â Restaurant Technology Updates"> 30<meta name="twitter:description" content="The latest INFI news: funding, partnerships, trade shows and events, company milestones, and product announcements from across our restaurant self-ordering platform."> 31<meta name="twitter:image" content="https://infi.us/img/og/news.jpg?v=3"> 32<link rel="icon" href="/favicon.ico" sizes="any"> 33<link rel="icon" href="/favicon.svg" type="image/svg+xml"> 34<link rel="icon" href="/favicon-48.png" sizes="48x48" type="image/png"> 35<link rel="icon" href="/favicon-32.png" sizes="32x32" type="image/png"> 36<link rel="apple-touch-icon" href="/apple-touch-icon.png"> 37<link rel="manifest" href="/site.webmanifest"> 38<link rel="preload" as="font" type="font/woff2" href="/fonts/clash-Z3MGHFHX6DCTLQ55LJYRJ5MDCZPMFZU6.woff2" crossorigin> 39<link rel="preload" as="font" type="font/woff2" href="/fonts/general-3ZLMEXZEQPLTEPMHTQDAUXP5ZZXCZAEN.woff2" crossorigin> 40<link rel="preload" as="font" type="font/woff2" href="/fonts/general-7YY3ZAAE3TRV2LANYOLXNHTPHLXVWTKH.woff2" crossorigin> 41 42<style> 43@font-face{font-family:'Clash Display';font-style:normal;font-weight:500;font-display:optional;src:url('/fonts/clash-JTSL5QESUXATU47LCPUNHZQBDDIWDOSW.woff2') format('woff2')} 44@font-face{font-family:'Clash Display';font-style:normal;font-weight:600;font-display:optional;src:url('/fonts/clash-Z3MGHFHX6DCTLQ55LJYRJ5MDCZPMFZU6.woff2') format('woff2')} 45@font-face{font-family:'Clash Display';font-style:normal;font-weight:700;font-display:optional;src:url('/fonts/clash-53RZKGODFYDW3QHTIL7IPOWTBCSUEZK7.woff2') format('woff2')} 46@font-face{font-family:'General Sans';font-style:normal;font-weight:400;font-display:optional;src:url('/fonts/general-7YY3ZAAE3TRV2LANYOLXNHTPHLXVWTKH.woff2') format('woff2')} 47@font-face{font-family:'General Sans';font-style:normal;font-weight:500;font-display:optional;src:url('/fonts/general-SB2OEB6IKZPRR6JT4GFJ2TFT6HBB6AZN.woff2') format('woff2')} 48@font-face{font-family:'General Sans';font-style:normal;font-weight:600;font-display:optional;src:url('/fonts/general-3ZLMEXZEQPLTEPMHTQDAUXP5ZZXCZAEN.woff2') format('woff2')} 49@font-face{font-family:'General Sans';font-style:normal;font-weight:700;font-display:optional;src:url('/fonts/general-NIQ54PVBBIWVK3PFSOIOUJSXIJ5WTNDP.woff2') format('woff2')} 50 51/* ============================================================================ 52 INFI â Restaurant Growth Platform · core design system 53 Bold, blue-forward, Apple/Square-caliber. Dual light + dark. 54 Type: Clash Display (display) + General Sans (body), self-hosted. 55 ========================================================================== */ 56
57/* ---------- TOKENS ---------- */ 58:root{ 59 /* brand blue â matches the real INFI kiosk hardware (cobalt + white) */ 60 --blue-50:#eef3ff; --blue-100:#dbe6ff; --blue-200:#b8ccff; --blue-300:#8aa9ff; 61 --blue-400:#5c83ff; --blue-500:#2f5dff; /* primary */ 62 --blue-600:#1f43e6; --blue-700:#1733b4; --blue-800:#142a8c; --blue-900:#0f1f5e; 63 --blue:var(--blue-500); 64 /* secondary accent â kept neutral within the Black/White/Gray/Blue palette 65 (the old amber accent was dropped; these aliases now resolve to blue so any 66 legacy .btn--amber / .amber-ink / amber bloom renders on-palette). */ 67 --amber-400:#8aa9ff; --amber:#5c83ff; --amber-600:#1f43e6; 68 /* ink / paper */ 69 --ink:#0a0e1a; --ink-2:#141a2e; 70 --paper:#ffffff; --paper-2:#f4f7fd; --paper-3:#e9effb; 71 72 /* semantic â LIGHT */ 73 --bg:var(--paper); 74 --bg-soft:var(--paper-2); 75 --surface:#ffffff; 76 --text:#0a0e1a; 77 --text-2:#41496a; 78 --text-3:#4f5a78; 79 --line:rgba(16,32,94,.12); 80 --line-2:rgba(16,32,94,.07); 81 --brand:var(--blue-500); 82 --brand-text:var(--blue-700); /* brand color used as small text â darker for stronger AA on glass */ 83 --on-brand:#ffffff; 84 --ring:rgba(47,93,255,.35); 85 --shadow-sm:0 1px 2px rgba(13,24,72,.07), 0 2px 8px rgba(13,24,72,.06); 86 /* crisper + a touch darker: cards must clearly lift off the toned-gray field */ 87 --shadow:0 4px 12px -4px rgba(13,24,72,.16), 0 18px 38px -14px rgba(13,24,72,.27); 88 --shadow-lg:0 8px 22px -8px rgba(13,24,72,.2), 0 46px 88px -34px rgba(13,24,72,.42); 89 --glow:0 0 0 1px rgba(47,93,255,.14), 0 30px 80px -30px rgba(47,93,255,.45); 90 91 /* type */ 92 --display:'Clash Display','General Sans',system-ui,sans-serif; 93 --body:'General Sans',system-ui,-apple-system,sans-serif; 94 --fw-disp:700; --fw-disp-2:600; 95 96 /* shape + space */ 97 --r-sm:12px; --r:18px; --r-lg:26px; --r-xl:34px; --r-pill:999px; 98 --maxw:1240px; --gut:clamp(20px,5vw,72px); 99 100 /* motion */ 101 --ease:cubic-bezier(.16,1,.3,1); 102 --ease-io:cubic-bezier(.65,0,.35,1); 103 --dur:.6s; 104 105 color-scheme:light; 106} 107 108@media (prefers-color-scheme: dark){html:not([data-theme="light"]){ 109 --bg:#06080f; 110 --bg-soft:#0a0e1a; 111 --surface:#101627; 112 --text:#f3f6ff; 113 --text-2:#aeb9da; 114 --text-3:#7e88ad; 115 --line:rgba(255,255,255,.12); 116 --line-2:rgba(255,255,255,.06); 117 --brand:#5c83ff; 118 --brand-text:#b3c6ff; 119 --ring:rgba(120,150,255,.45); 120 --shadow-sm:0 1px 2px rgba(0,0,0,.4); 121 --shadow:0 14px 40px -14px rgba(0,0,0,.6); 122 --shadow-lg:0 50px 110px -36px rgba(0,0,0,.75); 123 --glow:0 0 0 1px rgba(120,150,255,.18), 0 36px 90px -30px rgba(60,100,255,.5); 124 color-scheme:dark; 125 }} 126html[data-theme="dark"]{ 127 --bg:#06080f; 128 --bg-soft:#0a0e1a; 129 --surface:#101627; 130 --text:#f3f6ff; 131 --text-2:#aeb9da; 132 --text-3:#7e88ad; 133 --line:rgba(255,255,255,.12); 134 --line-2:rgba(255,255,255,.06); 135 --brand:#5c83ff; 136 --brand-text:#b3c6ff; 137 --ring:rgba(120,150,255,.45); 138 --shadow-sm:0 1px 2px rgba(0,0,0,.4); 139 --shadow:0 14px 40px -14px rgba(0,0,0,.6); 140 --shadow-lg:0 50px 110px -36px rgba(0,0,0,.75); 141 --glow:0 0 0 1px rgba(120,150,255,.18), 0 36px 90px -30px rgba(60,100,255,.5); 142 color-scheme:dark; 143 } 144 145 146/* ---------- RESET ---------- */ 147*,*::before,*::after{box-sizing:border-box} 148*{margin:0} 149/* overflow-x:clip on the ROOT (not just body) kills the horizontal scroll a phone 150 gets on first paint: every [data-rise="left"|"right"] reveal parks its element at 151 translateX(â48px) off-screen until the IntersectionObserver fires, so any below-fold 152 slide-in element overhangs the viewport edge and the page pans sideways until you 153 scroll it into view. body{overflow-x:clip} alone does NOT propagate to the viewport on 154 iOS Safari, so the pan survived; clipping at html contains it cross-browser. `clip` 155 (not hidden) creates no scroll container, so sticky/fixed nav + smooth-scroll are intact. */ 156html{-webkit-text-size-adjust:100%;scroll-behavior:smooth;overflow-x:clip} 157@media (prefers-reduced-motion: reduce){html{scroll-behavior:auto}} 158body{ 159 font-family:var(--body); 160 background:transparent; color:var(--text); /* transparent so the .amb toned field shows through (gives white glass its contrast) */ 161 line-height:1.6; font-weight:400; 162 -webkit-font-smoothing:antialiased; text-rendering:optimizeLegibility; 163 overflow-x:clip; 164} 165img,video,svg{display:block;max-width:100%;height:auto} 166a{color:inherit;text-decoration:none} 167button{font:inherit;color:inherit;background:none;border:0;cursor:pointer} 168::selection{background:var(--blue-500);color:#fff} 169 170/* ---------- TYPE SCALE (editorial, confident) ---------- */ 171/* word-spacing compensates Clash Display's very narrow space glyph (700 wt â .14em), 172 which the negative letter-spacing below otherwise collapses into word-jamming. 173 overflow-wrap guards every display heading from clipping off the right edge on 174 narrow mobile viewports (long words break instead of overflowing the viewport). */ 175.h-display{font-family:var(--display);font-weight:var(--fw-disp);line-height:.96;letter-spacing:-.03em;word-spacing:.12em; 176 overflow-wrap:break-word;font-size:clamp(2.4rem,7.4vw,6.6rem)} 177.h1{font-family:var(--display);font-weight:var(--fw-disp);line-height:1;letter-spacing:-.028em;word-spacing:.12em; 178 overflow-wrap:break-word;font-size:clamp(2.1rem,5.2vw,4.4rem)} 179.h2{font-family:var(--display);font-weight:var(--fw-disp);line-height:1.02;letter-spacing:-.025em;word-spacing:.12em; 180 overflow-wrap:break-word;font-size:clamp(1.8rem,4vw,3.4rem)} 181.h3{font-family:var(--display);font-weight:var(--fw-disp-2);line-height:1.08;letter-spacing:-.02em;word-spacing:.05em; 182 overflow-wrap:break-word;font-size:clamp(1.4rem,2.4vw,2.1rem)} 183/* Visually-hidden (screen-reader-only): used for bridge section headings that keep the 184 heading outline sequential (h1âh2âh3, no skips) without altering the visual design. */ 185.sr-only{position:absolute!important;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0} 186.lead{font-size:clamp(1.12rem,1.7vw,1.45rem);line-height:1.5;color:var(--text-2);font-weight:450;max-width:60ch;overflow-wrap:break-word} 187.eyebrow{font-family:var(--body);font-weight:600;font-size:.8rem;letter-spacing:.14em;text-transform:uppercase; 188 color:var(--brand-text);display:inline-flex;align-items:center;gap:.6em} 189.eyebrow::before{content:"";width:1.6em;height:1px;background:currentColor;opacity:.6} 190.muted{color:var(--text-3)} 191.amber-ink{color:var(--blue-600)} 192@media (prefers-color-scheme: dark){html:not([data-theme="light"]) .amber-ink{color:var(--blue-300)}} 193html[data-theme="dark"] .amber-ink{color:var(--blue-300)} 194 195 196/* gradient/clipped display accent word â all-blue (no warm stop) */ 197.grad{background:linear-gradient(108deg,var(--blue-600),var(--blue-400) 55%,var(--blue-300) 120%); 198 -webkit-background-clip:text;background-clip:text;color:transparent} 199 200/* ---------- LAYOUT ---------- */ 201.wrap{max-width:var(--maxw);margin-inline:auto;padding-inline:var(--gut)} 202.section{padding-block:clamp(60px,7vw,108px)} 203.section--tight{padding-block:clamp(40px,5vw,76px)} 204 205/* ---------- BUTTONS ---------- */ 206.btn{display:inline-flex;align-items:center;gap:.55em;font-family:var(--body);font-weight:600; 207 font-size:1rem;line-height:1;padding:1.05em 1.7em;border-radius:var(--r-pill); 208 transition:transform .25s var(--ease),box-shadow .25s var(--ease),background .25s,color .25s; 209 white-space:nowrap;will-change:transform} 210.btn:active{transform:translateY(1px) scale(.99)} 211.btn--primary{background:var(--blue-500);color:#fff;box-shadow:0 12px 30px -10px var(--ring)} 212.btn--primary:hover{background:var(--blue-600);transform:translateY(-2px);box-shadow:0 20px 44px -14px var(--ring)} 213.btn--amber{background:var(--blue-700);color:#fff;box-shadow:0 12px 30px -10px var(--ring)} 214.btn--amber:hover{background:var(--blue-800);transform:translateY(-2px)} 215.btn--ghost{background:color-mix(in srgb,var(--text) 6%,transparent);color:var(--text);border:1px solid var(--line)} 216.btn--ghost:hover{background:color-mix(in srgb,var(--text) 11%,transparent);transform:translateY(-2px)} 217.btn--lg{font-size:1.06rem;padding:1.15em 2em} 218.btn .ico{width:1.05em;height:1.05em;transition:transform .25s var(--ease)} 219.btn:hover .ico{transform:translateX(3px)} 220 221/* ---------- NAV â solid initially, frosted glass on scroll (Apple pattern) ---------- */ 222.nav{position:fixed;inset:0 0 auto;z-index:90; 223 background:var(--bg); 224 border-bottom:1px solid var(--line-2); 225 transition:background .4s,backdrop-filter .4s,border-color .35s,box-shadow .35s} 226.nav.is-stuck{ 227 background:color-mix(in srgb,var(--bg) 76%,transparent); 228 -webkit-backdrop-filter:saturate(200%) blur(20px);backdrop-filter:saturate(200%) blur(20px); 229 border-bottom-color:var(--line-2); 230 box-shadow:0 1px 0 var(--line-2),var(--glass-hi)} 231@media (prefers-color-scheme: dark){html:not([data-theme="light"]) .n
231av{background:var(--bg)}html:not([data-theme="light"]) .nav.is-stuck{background:color-mix(in srgb,var(--bg) 70%,transparent)}} 232html[data-theme="dark"] .nav{background:var(--bg)}html[data-theme="dark"] .nav.is-stuck{background:color-mix(in srgb,var(--bg) 70%,transparent)} 233 234.nav__in{display:flex;align-items:center;gap:30px;height:70px} 235.nav__logo{font-family:var(--display);font-weight:700;font-size:1.45rem;letter-spacing:.02em} 236.nav__links{display:flex;gap:6px;margin-left:14px} 237.nav__links a, .nav__has > button{display:inline-flex;align-items:center;gap:.3em;padding:.55em .8em;border-radius:10px;white-space:nowrap; 238 font-weight:500;font-size:.97rem;color:var(--text-2);transition:color .2s,background .2s} 239.nav__links a:hover,.nav__has:hover > button{color:var(--text);background:color-mix(in srgb,var(--text) 6%,transparent)} 240.nav__has{position:relative} 241.nav__drop{position:absolute;top:calc(100% + 8px);left:0;min-width:274px;padding:8px;border-radius:18px; 242 background:var(--surface);border:1px solid var(--line);box-shadow:var(--shadow-lg); 243 opacity:0;visibility:hidden;transform:translateY(8px);transition:.2s var(--ease)} 244.nav__has:hover .nav__drop,.nav__has:focus-within .nav__drop{opacity:1;visibility:visible;transform:none} 245.nav__drop a{display:block;padding:.6em .8em;border-radius:11px;color:var(--text-2);font-size:.94rem} 246.nav__drop a:hover{background:var(--bg-soft);color:var(--brand-text)} 247.nav__drop--right{left:auto;right:0;min-width:248px} 248/* Products menu, grouped by the job the capability does. A flat list of nine made a 249 first-time visitor read every item to find the one they wanted; the group headings 250 let them skip straight to the right shelf. Headings are <p>, not links. */ 251.nav__drop--groups{min-width:302px;padding:10px 8px;max-height:calc(100vh - 96px);overflow-y:auto} 252.nav__grp{margin:13px 10px 4px;font-family:var(--body);font-weight:700;font-size:.67rem; 253 letter-spacing:.13em;text-transform:uppercase;color:var(--text-3)} 254.nav__grp:first-of-type{margin-top:7px} 255.nav__drop--groups .nav__ov{font-weight:600;color:var(--text)} 256.mnav__grp{margin:20px 4px 2px;font-family:var(--body);font-weight:700;font-size:.7rem; 257 letter-spacing:.13em;text-transform:uppercase;color:var(--text-3)} 258.nav__drop a small{display:block;font-size:.74rem;color:var(--text-3);font-weight:500;margin-top:1px} 259.nav__has--login>button{cursor:pointer;background:none;border:0;font:inherit} 260.nav__cta{margin-left:auto;display:flex;align-items:center;gap:12px} 261.nav__login{font-weight:500;color:var(--text-2);padding:.55em .7em} 262.nav__login:hover{color:var(--text)} 263/* ---------- THEME TOGGLE BUTTON ---------- */ 264/* Auto/Light/Dark segmented theme control (footer + mobile drawer) */ 265.themebox{display:flex;align-items:center;gap:12px;flex-wrap:wrap} 266.themebox__lbl{font-size:.78rem;font-weight:600;color:var(--text-3)} 267.themeseg{display:inline-flex;gap:3px;padding:3px;border-radius:var(--r-pill);border:1px solid var(--line);background:color-mix(in srgb,var(--text) 5%,transparent)} 268.themeseg button{appearance:none;-webkit-appearance:none;border:0;background:transparent;cursor:pointer;font-family:inherit;font-size:.76rem;font-weight:600;color:var(--text-3);padding:.36em .85em;border-radius:var(--r-pill);transition:color .2s,background .2s} 269.themeseg button:hover{color:var(--text)} 270.themeseg button[aria-pressed="true"]{background:var(--blue-500);color:#fff} 271.foot .themebox__lbl{color:#9aa7c4} 272.foot .themeseg{border-color:rgba(255,255,255,.16);background:rgba(255,255,255,.05)} 273.foot .themeseg button{color:#aeb9d4}.foot .themeseg button:hover{color:#fff} 274.foot .themeseg button[aria-pressed="true"]{background:var(--blue-500);color:#fff} 275.mnav__theme{margin-top:16px} 276 277@media (max-width:900px){.nav__links,.nav__login,.nav__has--login{display:none}} 278/* MOBILE NAV FIT â the logo <img> was the only shrinkable flex item in a too-wide 279 row (big gap + Book-a-Demo button), so it got squeezed to ~50px wide while its 280 height stayed 23px â the wordmark looked STRETCHED. Lock the logo to its natural 281 aspect (never shrink, ignore the global img max-width:100%) and tighten the row. */
282@media (max-width:900px){ 283 .nav__in{gap:14px} 284 .nav__logo{flex:0 0 auto} 285 .nav__logo img{max-width:none;width:auto} 286} 287@media (max-width:380px){ 288 /* tightest phones: trim the CTA so logo + toggle + CTA + burger still fit cleanly */ 289 .nav__in{gap:10px} 290 .nav .nav__cta .btn--primary{padding:.85em 1.05em;font-size:.92rem} 291} 292 293/* ---------- FOOTER ---------- */ 294.foot{background:var(--ink);color:#c7cfe6;padding-block:clamp(56px,7vw,96px) 34px; 295 border-top:1px solid rgba(255,255,255,.08)} 296@media (prefers-color-scheme: dark){html:not([data-theme="light"]) .foot{background:#04060c}} 297html[data-theme="dark"] .foot{background:#04060c} 298 299.foot__grid{display:grid;grid-template-columns:1.5fr repeat(3,1fr);gap:40px} 300.foot__brand .nav__logo{color:#fff;font-size:1.6rem} 301.foot__tag{margin-top:14px;max-width:34ch;color:#8c97b8;font-size:.95rem} 302.foot h4{color:#fff;font-size:.82rem;letter-spacing:.1em;text-transform:uppercase;margin-bottom:14px;font-weight:600} 303.foot a{color:#aab4d2;font-size:.94rem;display:block;padding:5px 0;transition:color .2s} 304.foot a:hover{color:#fff} 305.foot__bar{display:flex;justify-content:space-between;align-items:center;flex-wrap:wrap;gap:14px; 306 margin-top:46px;padding-top:26px;border-top:1px solid rgba(255,255,255,.1);color:#7e88ad;font-size:.88rem} 307.foot__legal{display:flex;gap:18px;flex-wrap:wrap} 308.foot__legal a{display:inline;padding:0;color:#7e88ad;font-size:.88rem} 309.foot__legal a:hover{color:#fff} 310@media (max-width:760px){.foot__grid{grid-template-columns:1fr 1fr}.foot__brand{grid-column:1/-1}} 311 312/* ---------- MOTION UTILITIES (reveal-once, JS-gated, reduced-motion safe) ---------- */ 313@media (prefers-reduced-motion: no-preference){ 314 html.js [data-reveal]{opacity:0;transform:translateY(30px); 315 transition:opacity 1.6s var(--ease),transform 1.6s var(--ease)} 316 html.js [data-reveal].in{opacity:1;transform:none} 317 html.js [data-reveal="scale"]{transform:translateY(24px) scale(.96)} 318 html.js [data-reveal] [data-stagger]{opacity:0;transform:translateY(20px); 319 transition:opacity 1.4s var(--ease),transform 1.4s var(--ease)} 320 html.js [data-reveal].in [data-stagger]{opacity:1;transform:none} 321} 322.focus-ring:focus-visible,a:focus-visible,button:focus-visible{outline:2px solid var(--brand);outline-offset:3px;border-radius:8px} 323 324/* ============================================================================ 325 LIQUID GLASS LAYER â Apple Liquid Glass reference (8.02.02) + Dribbble refs. 326 Key: 2px bright top-edge refraction, gradient fill, strong blur (40px), 327 saturated ambient field that shows through the glass. Thick glass, not film. 328 ========================================================================== */ 329:root{ 330 /* glass fill: lighter on top (refracted light) â translucent on bottom */ 331 --glass:rgba(255,255,255,.36); /* clearer glass â the field/atmosphere refracts through */ 332 --glass-strong:rgba(255,255,255,.6); 333 --glass-brd:rgba(255,255,255,0); /* FRAMELESS â no border (user removed it) */ 334 --glass-brd-soft:rgba(255,255,255,0); 335 /* THE SIGNATURE (frameless thick glass): bright TOP specular edge + a soft 336 COOL INNER REFRACTION GLOW (light bending inside the slab) + a DARK 337 BOTTOM-INNER BEVEL. No full-perimeter outline. Consumed by every card 338 sitewide (.glass, .pcard, .stat, .poschip, .velo__c, .comp.glass â¦). */ 339 --glass-hi: 340 inset 0 1.5px 0 rgba(255,255,255,.95), 341 inset 0 16px 36px -18px rgba(120,160,255,.32), 342 inset 0 -22px 34px -22px rgba(14,28,66,.48), 343 inset 0 -3px 2px -1px rgba(14,28,66,.12); 344 /* stronger frosted blur so the refraction reads clearly â atmosphere shows through */ 345 --glass-blur: saturate(235%) blur(48px) brightness(1.03); 346 /* convex top sheen layer for .glass panels (curved glass face) */ 347 --glass-sheen:radial-gradient(155% 110% at 30% -22%, rgba(255,255,255,.55), rgba(255,255,255,.1) 38%, rgba(255,255,255,0) 60%); 348 /* ambient field: TONED gray (not near-white) so white glass pops, + an edge 349 vignette so even centre panels sit against a gradient. */ 350 --amb-base:#dce3ee; 351 --amb-1:rgba(120,90,235,.17); /* cyan-blue â left bloom (cooled to kill any violet cast) */ 352 --amb-2:rgba(55,185,225,.15); /* cyan-blue â top-right, soft */ 353 --amb-3:rgba(228,100,190,.13); /* slate echo (was amber) */ 354 --amb-4:rgba(70,120,255,.15); /* bottom-right corner */ 355 --amb-vignette:rgba(18,34,76,.17); 356} 357@media (prefers-color-scheme: dark){html:not([data-theme="light"]){ 358 --glass:rgba(22,32,72,.4); 359 --glass-strong:rgba(30,46,100,.6); 360 --glass-brd:rgba(255,255,255,0); 361 --glass-brd-soft:rgba(255,255,255,0); 362 --glass-hi: 363 inset 0 1.5px 0 rgba(255,255,255,.3), 364 inset 0 16px 38px -18px rgba(90,140,255,.34), 365 inset 0 -18px 30px -22px rgba(0,0,0,.58), 366 inset 0 -2px 1px rgba(0,0,0,.4); 367 --glass-blur: saturate(220%) blur(48px) brightness(1.05); 368 --glass-sheen:radial-gradient(155% 110% at 30% -22%, rgba(255,255,255,.22), rgba(255,255,255,.05) 38%, rgba(255,255,255,0) 58%); 369 --amb-base:#04060e; 370 --amb-1:rgba(130,80,255,.44); 371 --amb-2:rgba(40,165,225,.40); 372 --amb-3:rgba(215,85,185,.26); /* slate (was amber) */ 373 --amb-4:rgba(70,120,255,.34); 374 --amb-vignette:rgba(0,0,0,.6); 375 }}
376html[data-theme="dark"]{ 377 --glass:rgba(22,32,72,.4); 378 --glass-strong:rgba(30,46,100,.6); 379 --glass-brd:rgba(255,255,255,0); 380 --glass-brd-soft:rgba(255,255,255,0); 381 --glass-hi: 382 inset 0 1.5px 0 rgba(255,255,255,.3), 383 inset 0 16px 38px -18px rgba(90,140,255,.34), 384 inset 0 -18px 30px -22px rgba(0,0,0,.58), 385 inset 0 -2px 1px rgba(0,0,0,.4); 386 --glass-blur: saturate(220%) blur(48px) brightness(1.05); 387 --glass-sheen:radial-gradient(155% 110% at 30% -22%, rgba(255,255,255,.22), rgba(255,255,255,.05) 38%, rgba(255,255,255,0) 58%); 388 --amb-base:#04060e; 389 --amb-1:rgba(130,80,255,.44); 390 --amb-2:rgba(40,165,225,.40); 391 --amb-3:rgba(215,85,185,.26); /* slate (was amber) */ 392 --amb-4:rgba(70,120,255,.34); 393 --amb-vignette:rgba(0,0,0,.6); 394 } 395 396/* fixed ambient field â must be VIVID to show through glass */ 397html{background:var(--amb-base)} 398.amb{position:fixed;inset:0;z-index:-2;pointer-events:none;overflow:hidden; 399 background: 400 radial-gradient(125% 115% at 50% 32%, transparent 44%, var(--amb-vignette) 100%), 401 radial-gradient(56vmax 50vmax at 8% -4%, var(--amb-1), transparent 58%), 402 radial-gradient(48vmax 44vmax at 96% 8%, var(--amb-2), transparent 60%), 403 radial-gradient(58vmax 52vmax at 82% 96%, var(--amb-4), transparent 58%), 404 radial-gradient(42vmax 38vmax at 14% 98%, var(--amb-3), transparent 56%), 405 var(--amb-base)} 406 407/* ===== AMBIENT ATMOSPHERE â drifting geo blobs + slow light beams on EVERY page 408 (the home hero's signature flow effect, made reusable). Gives the now-clearer 409 glass colourful motion to refract. Pure transform/opacity, reduced-motion safe. */ 410.amb__geo{position:absolute;border-radius:50%;pointer-events:none;will-change:transform} 411.amb__g1{width:42vw;height:42vw;right:-10vw;top:-12vw; 412 background:radial-gradient(circle at 42% 40%,rgba(47,93,255,.30),rgba(47,93,255,0) 64%);filter:blur(12px);animation:ambflow1 26s var(--ease-io) infinite alternate} 413.amb__g2{width:34vw;height:34vw;left:-12vw;top:32vh; 414 background:radial-gradient(circle at 50% 50%,rgba(40,170,255,.22),transparent 62%);filter:blur(14px);animation:ambflow2 32s var(--ease-io) infinite alternate} 415.amb__g3{width:30vw;height:30vw;right:6vw;bottom:-12vw; 416 background:radial-gradient(circle at 50% 50%,rgba(96,150,255,.20),transparent 64%);filter:blur(14px);animation:ambflow3 30s var(--ease-io) infinite alternate} 417.amb__ring{position:absolute;left:-8vw;top:6vh;width:32vw;height:32vw;border-radius:50%; 418 border:1px solid rgba(47,93,255,.13); 419 -webkit-mask:radial-gradient(circle,transparent 57%,#000 59%);mask:radial-gradient(circle,transparent 57%,#000 59%); 420 animation:ambspin 80s linear infinite} 421.amb__beam{position:absolute;height:1.5px;width:160%;left:-30%;pointer-events:none; 422 background:linear-gradient(90deg,transparent,rgba(120,160,255,.55),transparent);filter:blur(.5px)} 423.amb__b1{top:28%;transform:rotate(-10deg);animation:ambbeam 11s linear infinite} 424.amb__b2{top:74%;transform:rotate(-10deg);animation:ambbeam 15s linear infinite 4s} 425@keyframes ambflow1{to{transform:translate3d(6%,5%,0) scale(1.12)}} 426@keyframes ambflow2{to{transform:translate3d(-5%,7%,0) scale(1.15)}} 427@keyframes ambflow3{to{transform:translate3d(5%,-6%,0) scale(1.1)}} 428@keyframes ambspin{to{transform:rotate(360deg)}} 429@keyframes ambbeam{0%{opacity:0;transform:translateX(-14%) rotate(-10deg)}12%{opacity:.7}84%{opacity:.5}100%{opacity:0;transform:translateX(14%) rotate(-10deg)}} 430@media (prefers-color-scheme: dark){html:not([data-theme="light"]) .amb__g1{background:radial-gradient(circle at 42% 40%,rgba(55,100,255,.5),transparent 64%)}html:not([data-theme="light"]) .amb__g2{background:radial-gradient(circle at 50% 50%,rgba(40,150,255,.36),transparent 62%)}html:not([data-theme="light"]) .amb__g3{background:radial-gradient(circle at 50% 50%,rgba(96,150,255,.34),transparent 64%)}html:not([data-theme="light"]) .amb__beam{background:linear-gradient(90deg,transparent,rgba(140,180,255,.85),transparent)}html:not([data-theme="light"]) .amb__ring{border-color:rgba(120,150,255,.2)}} 431html[data-theme="dark"] .amb__g1{background:radial-gradient(circle at 42% 40%,rgba(55,100,255,.5),transparent 64%)}html[data-theme="dark"] .amb__g2{background:radial-gradient(circle at 50% 50%,rgba(40,150,255,.36),transparent 62%)}html[data-theme="dark"] .amb__g3{background:radial-gradient(circle at 50% 50%,rgba(96,150,255,.34),transparent 64%)}html[data-theme="dark"] .amb__beam{background:linear-gradient(90deg,transparent,rgba(140,180,255,.85),transparent)}html[data-theme="dark"] .amb__ring{border-color:rgba(120,150,255,.2)} 432 433@media (prefers-reduced-motion:reduce){.amb__geo,.amb__ring{animation:none}.amb__beam{display:none}} 434 435/* frosted glass panel â convex sheen + gradient fill = Apple thick-glass look. 436 The sheen radial sits on top of the fill (curved top face cat
436ching light); 437 --glass-hi paints the bright-top + dark-bottom bevel that sells thickness. */ 438.glass{ 439 background: 440 var(--glass-sheen), 441 radial-gradient(120% 130% at 112% 116%, rgba(70,140,255,.16), transparent 52%), 442 radial-gradient(120% 120% at -12% -8%, rgba(150,200,255,.12), transparent 50%), 443 linear-gradient(168deg, rgba(255,255,255,.4) 0%, rgba(255,255,255,.16) 100%); 444 -webkit-backdrop-filter:var(--glass-blur); backdrop-filter:var(--glass-blur); 445 border:1px solid var(--glass-brd-soft); 446 box-shadow:var(--glass-hi), 0 24px 64px -18px rgba(20,50,160,.2), var(--shadow); 447} 448.glass--strong{ 449 background: 450 var(--glass-sheen), 451 linear-gradient(168deg, rgba(255,255,255,.72) 0%, rgba(255,255,255,.46) 100%); 452 border-color:var(--glass-brd); 453 box-shadow: 454 inset 0 2.5px 0 rgba(255,255,255,1), 455 inset 0 0 0 2px rgba(255,255,255,.66), 456 inset 0 -18px 30px -22px rgba(14,28,66,.5), 457 inset 0 -2px 1px rgba(14,28,66,.14), 458 0 34px 82px -20px rgba(20,50,160,.28), 459 var(--shadow-lg); 460} 461@media (prefers-color-scheme: dark){html:not([data-theme="light"]) .glass{ 462 background: 463 var(--glass-sheen), 464 linear-gradient(168deg, rgba(40,64,160,.52) 0%, rgba(18,34,90,.34) 100%); 465 box-shadow:var(--glass-hi), 0 24px 64px -18px rgba(0,0,0,.56), var(--shadow); 466 }html:not([data-theme="light"]) .glass--strong{ 467 background: 468 var(--glass-sheen), 469 linear-gradient(168deg, rgba(52,80,180,.62) 0%, rgba(24,44,110,.44) 100%); 470 box-shadow: 471 inset 0 2.5px 0 rgba(255,255,255,.4), 472 inset 0 0 0 2px rgba(255,255,255,.2), 473 inset 0 -20px 32px -22px rgba(0,0,0,.62), 474 inset 0 -2px 1px rgba(0,0,0,.42), 475 0 34px 82px -20px rgba(0,0,0,.72), 476 var(--shadow-lg); 477 }} 478html[data-theme="dark"] .glass{ 479 background: 480 var(--glass-sheen), 481 linear-gradient(168deg, rgba(40,64,160,.52) 0%, rgba(18,34,90,.34) 100%); 482 box-shadow:var(--glass-hi), 0 24px 64px -18px rgba(0,0,0,.56), var(--shadow); 483 }html[data-theme="dark"] .glass--strong{ 484 background: 485 var(--glass-sheen), 486 linear-gradient(168deg, rgba(52,80,180,.62) 0%, rgba(24,44,110,.44) 100%); 487 box-shadow: 488 inset 0 2.5px 0 rgba(255,255,255,.4), 489 inset 0 0 0 2px rgba(255,255,255,.2), 490 inset 0 -20px 32px -22px rgba(0,0,0,.62), 491 inset 0 -2px 1px rgba(0,0,0,.42), 492 0 34px 82px -20px rgba(0,0,0,.72), 493 var(--shadow-lg); 494 } 495 496 497/* nav becomes a floating glass capsule */ 498.nav__in{margin-top:0} 499.nav.is-stuck{ 500 background: linear-gradient(180deg, rgba(255,255,255,.92) 0%, rgba(255,255,255,.78) 100%); 501 border-bottom-color:rgba(255,255,255,.85); 502 -webkit-backdrop-filter:var(--glass-blur);backdrop-filter:var(--glass-blur); 503 box-shadow:inset 0 2px 0 rgba(255,255,255,1),0 8px 32px -8px rgba(20,50,160,.14); 504} 505@media (prefers-color-scheme: dark){html:not([data-theme="light"]) .nav.is-stuck{ 506 background: linear-gradient(180deg, rgba(28,42,100,.86) 0%, rgba(18,28,72,.70) 100%); 507 border-bottom-color:rgba(255,255,255,.14); 508 box-shadow:inset 0 1.5px 0 rgba(255,255,255,.24),0 8px 32px -8px rgba(0,0,0,.5); 509 }} 510html[data-theme="dark"] .nav.is-stuck{ 511 background: linear-gradient(180deg, rgba(28,42,100,.86) 0%, rgba(18,28,72,.70) 100%); 512 border-bottom-color:rgba(255,255,255,.14); 513 box-shadow:inset 0 1.5px 0 rgba(255,255,255,.24),0 8px 32px -8px rgba(0,0,0,.5); 514 } 515 516 517/* card sheen on hover â more luminous refraction sweep */ 518.sheen{position:relative;overflow:hidden} 519.sheen::before{content:"";position:absolute;inset:0;pointer-events:none;opacity:0; 520 background:linear-gradient(115deg, 521 transparent 28%, 522 rgba(255,255,255,.15) 38%, 523 rgba(255,255,255,.75) 47%, 524 rgba(255,255,255,.90) 50%, 525 rgba(255,255,255,.75) 53%, 526 rgba(255,255,255,.15) 62%, 527 transparent 72%); 528 transform:translateX(-35%);transition:opacity .45s,transform .85s var(--ease)} 529.sheen:hover::before{opacity:1;transform:translateX(35%)} 530@media (prefers-color-scheme: dark){html:not([data-theme="light"]) .sheen::before{background:linear-gradient(115deg,transparent 28%,rgba(255,255,255,.04) 38%,rgba(255,255,255,.22) 50%,rgba(255,255,255,.04) 62%,transparent 72%)}} 531html[data-theme="dark"] .sheen::before{background:linear-gradient(115deg,transparent 28%,rgba(255,255,255,.04) 38%,rgba(255,255,255,.22) 50%,rgba(255,255,255,.04) 62%,transparent 72%)} 532 533
534/* ===== UNIFIED GLASS-CARD HOVER â ONE consistent lift + cool rim-glow on every 535 glass surface sitewide. body-prefixed so it beats per-page inline `.card:hover` 536 rules by specificity (0,2,1 > 0,2,0), giving identical hover behaviour everywhere. */ 537body :is(.glass,.glass--strong,.pcard,.stat,.fcard,.hwc,.poschip,.velo__c,.spec-card,.merch-card,.repcard,.syncc,.qcard,.tcard,.vcard,.sol,.fc,.eco-hub__node--peer){ 538 transition:transform .45s var(--ease),box-shadow .45s var(--ease),background .4s var(--ease)} 539@media (prefers-reduced-motion:no-preference){ 540 body :is(.glass,.pcard,.stat,.fcard,.hwc,.poschip,.velo__c,.spec-card,.merch-card,.repcard,.syncc,.qcard,.tcard,.vcard,.fc,.eco-hub__node--peer):hover{ 541 transform:translateY(-6px); 542 box-shadow:var(--glass-hi), inset 0 0 0 1px rgba(150,190,255,.22), 0 0 30px -8px rgba(80,140,255,.32), 0 28px 64px -24px rgba(20,50,160,.42), var(--shadow-lg)} 543 body :is(.sol):hover{transform:translateY(-6px) scale(1.012)} 544} 545@media (prefers-reduced-transparency: reduce){ 546 :root{--glass:#fff;--glass-strong:#fff;--glass-blur:none} 547 @media (prefers-color-scheme: dark){:root{--glass:#121a2e;--glass-strong:#16203a}} 548} 549 550.foot__h{font-size:.95rem;letter-spacing:.04em;text-transform:uppercase;font-weight:700;color:rgba(255,255,255,.9);margin:0 0 14px} 551 552/* ============================================================================ 553 MAGIC MOVE â cross-document View Transitions (Keynote-style shared-element morph) 554 Pages behave like slides. Any element that carries the SAME `view-transition-name` 555 on two pages morphs from its position/size/appearance on the page you leave into 556 the one you arrive at. Native + progressive: browsers without support just navigate. 557 Shared names are assigned per page (home product cards â product-page heroes, home 558 industry tiles â solution-page heroes). nav + footer persist so the frame holds still. 559 ========================================================================== */ 560@view-transition{ navigation:auto; } 561 562@media (prefers-reduced-motion: no-preference){ 563 /* every morphing pair travels + eases like Magic Move */ 564 ::view-transition-group(*){ animation-duration:.62s; animation-timing-function:var(--ease); } 565 ::view-transition-image-pair(*){ animation-duration:.62s; animation-timing-function:var(--ease); } 566 /* unmatched page content: gentle lift + fade so it reads as intentional, not a flash */ 567 ::view-transition-old(root){ animation:mm-out .40s var(--ease) both; } 568 ::view-transition-new(root){ animation:mm-in .52s var(--ease) both; } 569} 570@keyframes mm-out{ to{ opacity:0; transform:scale(.99) translateY(-8px); } } 571@keyframes mm-in{ from{ opacity:0; transform:scale(1.01) translateY(12px); } } 572 573@media (prefers-reduced-motion: reduce){ 574 ::view-transition-group(*),::view-transition-image-pair(*),::view-transition-old(*),::view-transition-new(*){ animation:none !important; } 575} 576 577/* persistent chrome â identical name on every page â nav & footer stay put (the slide 578 frame) while the shared object morphs between them */ 579.nav{ view-transition-name:vt-nav; } 580.foot{ view-transition-name:vt-foot; } 581 582/* ============================================================================ 583 MOBILE OPTIMIZATION â performance-first glass + touch-native motion (â¤760px) 584 The phone experience was "much worse" for two reasons screenshots can't show: 585 (1) backdrop-filter:blur(48px) re-samples the backdrop EVERY scroll frame on 586 20-34 glass cards per page â severe scroll jank on real phones; and 587 (2) the rich desktop motion (hover sheen, card lift) is pointer-only, so touch 588 got a flat, lifeless surface. 589 Fixes: the blur radius is the dominant GPU cost, so it's cut hard â the frosted 590 look is carried by the gradient fill + bright top edge, which stay; touch gets 591 its own press + reveal-shimmer vocabulary. `html:root` (0,1,1) placed AFTER the 592 dark [data-theme] blocks wins the token-override specificity war in every theme. 593 ========================================================================== */ 594@media (max-width:760px){ 595 html:root{ 596 /* frosted, but ~3x cheaper to sample â visually near-identical at phone DPR */ 597 --glass-blur:saturate(170%) blur(18px); 598 --gut:clamp(17px,5.2vw,72px); 599 } 600 /* the nav/mobile-menu frost can stay a touch heavier (one element, not per-card) */ 601 .mnav{-webkit-backdrop-filter:saturate(180%) blur(20px);backdrop-filter:saturate(180%) blur(20px)} 602 /* trim the giant blob blur a notch â fixed field, cheaper raster, same colour */ 603 .amb__g1,.amb__g3{filter:blur(10px)} 604 .amb__g2{filter:blur(11px)}
605 /* SCROLL-PROGRESS BAR â a phone-only signature flourish. Pure CSS via body::before 606 + a scroll-driven timeline (GPU-composited, runs off the main thread = buttery). 607 @supports-gated so browsers without scroll-driven animation simply never paint it 608 (zero cost, no JS, no markup). The blue gradient echoes the changelog spine. */ 609 @supports (animation-timeline:scroll()){ 610 body::before{content:"";position:fixed;top:0;left:0;right:0;height:3px;z-index:200; 611 transform:scaleX(0);transform-origin:0 50%;pointer-events:none; 612 background:linear-gradient(90deg,var(--blue-400),var(--blue-600) 55%,var(--blue-400)); 613 box-shadow:0 0 12px -1px rgba(47,93,255,.55); 614 animation:scrollprog linear both;animation-timeline:scroll(root)} 615 } 616} 617@keyframes scrollprog{to{transform:scaleX(1)}} 618 619/* TOUCH-NATIVE PRESS â tactile feedback that replaces the hover-lift on phones. 620 Cards/links/buttons give a quick, springy push-in when tapped (iOS-like). */ 621@media (hover:none){ 622 body :is(.glass,.glass--strong,.pcard,.stat,.fcard,.hwc,.poschip,.velo__c,.spec-card, 623 .merch-card,.repcard,.syncc,.qcard,.tcard,.vcard,.sol,.fc,.quote,.eco-hub__node--peer, 624 .hub-m__n,.pos-logo):active{ 625 transform:scale(.972); 626 transition:transform .11s var(--ease); 627 } 628 .btn:active{transform:scale(.96)} 629 /* kill the sticky-hover lift that otherwise gets stuck "up" after a tap on touch */ 630 @media (prefers-reduced-motion:no-preference){ 631 body :is(.glass,.pcard,.stat,.fcard,.hwc,.poschip,.velo__c,.spec-card,.merch-card, 632 .repcard,.syncc,.qcard,.tcard,.vcard,.fc,.eco-hub__node--peer):hover{transform:none} 633 body :is(.sol):hover{transform:none} 634 .sol:hover img{transform:none} 635 } 636} 637 638/* REVEAL-SHIMMER â the .sheen light-sweep is hover-driven, so it never fires on 639 touch. Replay it ONCE, gently, as each sheen card scrolls into view: the phone 640 gets the signature liquid-glass light pass instead of a dead surface. */ 641@media (hover:none) and (prefers-reduced-motion:no-preference){ 642 html.js [data-rise].in .sheen::before, 643 html.js [data-rise].in.sheen::before{ 644 animation:sheen-reveal 2.3s var(--ease) .24s 1 both; 645 } 646} 647@keyframes sheen-reveal{ 648 0%{opacity:0;transform:translateX(-40%)} 649 34%{opacity:.62} 650 100%{opacity:0;transform:translateX(40%)} 651} 652 653/* MOBILE MENU MUST SCROLL â the full-screen menu's content (8 products + sections + 654 sign-in + the Book-a-Demo CTA) is taller than a phone viewport, but it shipped with 655 overflow:visible, so the bottom items (the CTA included) were clipped and unreachable 656 on shorter phones. `.mnav.mnav` (0,2,0) outranks the per-page inline `.mnav` (0,1,0) 657 in every theme, so this fixes home + all built pages from the one shared sheet. */ 658.mnav.mnav{overflow-y:auto;overscroll-behavior:contain;-webkit-overflow-scrolling:touch} 659/* a little extra bottom breathing room so the CTA clears any phone home-indicator */ 660.mnav{padding-bottom:max(40px,env(safe-area-inset-bottom,0px))} 661 662/* ============================================================================ 663 MOBILE AUDIT FIXES (multi-agent audit, adversarially verified) 664 ========================================================================== */ 665/* iOS FOCUS-ZOOM GUARD â any form field <16px makes iOS Safari zoom the viewport on 666 focus (worst on the /demo/ request form, the primary conversion path). The page's 667 `.form-field input` rule is (0,1,1); `html:root :is(...)` is (0,1,2) so it wins in 668 every theme regardless of source order. :is() (not a comma list) elevates all three. */ 669@media (max-width:760px){ 670 html:root :is(input,select,textarea){font-size:16px} 671} 672/* TOUCH TARGETS â footer links were 34px tall (â10px between ~10 stacked links â mis-taps); 673 the theme toggle was 40px. Apple's min is 44. */ 674@media (max-width:760px){ .foot a{padding-top:9px;padding-bottom:9px} } /* â ~42px tall + 18px gap */ 675@media (max-width:900px){ } /* nav row has slack; icon stays 19px */ 676/* PERF â flatten small decorative glass chips on mobile. After the blur-radius cut they 677 still pay per-frame backdrop sampling for frost that's invisible at chip size over the 678 near-uniform field. Drop the backdrop-filter, keep the bevel+shadow so they still read 679 as raised glass. `body :is()` (0,1,1) beats the per-page inline chip rules (0,1,0). */ 680@media (max-width:760px){ 681 body :is(.poschip,.valstat,.sqbadge){ 682 -webkit-backdrop-filter:none;backdrop-filter:none; 683 background:var(--bg-soft); 684 } 685} 686 687/* mobile fold removed â content kept visible; copy simplified instead */ 688.foldbtn{display:none!important} 689 690 691/* infi-scrollbar â INFI-branded scrollbar, dual light/dark */ 692html{scrollbar-width:thin;scrollbar-color:var(--blue-500,#2f5dff) transparent} 693::-webkit-scrollbar{width:12px;height:12px} 694::-webkit-scrollbar-track{background:transparent} 695::-webkit-scrollbar-thumb{background-color:var(--blue-500,#2f5dff);border-radius:999px} 696::-webkit-scrollbar-thumb:hover{background-color:var(--blue-600,#1f43e6)} 697::-webkit-scrollbar-corner{background:transparent} 698html[data-theme="dark"]{scrollbar-color:var(--blue-400,#5c83ff) transparent} 699html[data-theme="dark"] ::-webkit-scrollbar-thumb{background-color:var(--blue-400,#5c83ff)} 700html[data-theme="dark"] ::-webkit-scrollbar-thumb:hover{background-color:var(--blue-300,#8aa9ff)} 701@media(prefers-color-scheme:dark){html:not([data-theme="light"]){scrollbar-color:var(--blue-400,#5c83ff) transparent} 702html:not([data-theme="light"]) ::-webkit-scrollbar-thumb{background-color:var(--blue-400,#5c83ff)} 703html:not([data-theme="light"]) ::-webkit-scrollbar-thumb:hover{background-color:var(--blue-300,#8aa9ff)}} 704 705main{position:relative;z-index:1} 706.nav__logo{display:inline-flex;align-items:center}.nav__logo img{height:23px;width:auto;display:block} 707.lg-d{display:none!important}@media (prefers-color-scheme: dark){html:not([data-theme="light"]) .lg-l{display:none!important}html:not([data-theme="light"]) .lg-d{display:block!important}}html[data-theme="dark"] .lg-l{display:none!important}html[data-theme="dark"] .lg-d{display:block!important} 708.eyebrow::before{width:.5em;height:.5em;border-radius:1.5px;background:var(--blue-500);opacity:1} 709.section img:not(.pcard__ico svg){border-radius:var(--r-lg)} 710/* mobile nav (shared) */ 711.nav__burger{display:none;margin-left:auto;width:44px;height:44px;border-radius:12px;align-items:center;justify-content:center;background:var(--glass-strong);border:1px solid var(--glass-brd-soft)}
712.nav__burger span{display:block;width:18px;height:2px;background:var(--text);border-radius:2px;position:relative;transition:.3s var(--ease)} 713.nav__burger span::before,.nav__burger span::after{content:"";position:absolute;left:0;width:18px;height:2px;background:var(--text);border-radius:2px;transition:.3s var(--ease)} 714.nav__burger span::before{top:-6px}.nav__burger span::after{top:6px} 715.mnav{position:fixed;inset:0;z-index:95;background:var(--glass-strong);-webkit-backdrop-filter:blur(26px) saturate(180%);backdrop-filter:blur(26px) saturate(180%);display:flex;flex-direction:column;padding:88px 24px 32px;gap:6px;transform:translateY(-100%);visibility:hidden;overflow-y:auto;-webkit-overflow-scrolling:touch;overscroll-behavior:contain;transition:transform .45s var(--ease),visibility .45s} 716.mnav.open{transform:none;visibility:visible} 717.mnav a{font-family:var(--display);font-weight:600;font-size:1.5rem;letter-spacing:-.02em;padding:12px 4px;border-bottom:1px solid var(--line-2);color:var(--text)} 718.mnav a small{display:block;font-family:var(--body);font-weight:500;font-size:.8rem;color:var(--text-3);letter-spacing:0;margin-top:2px} 719.mnav .btn{margin-top:18px;justify-content:center} 720.mnav__x{position:absolute;top:18px;right:20px;width:42px;height:42px;border-radius:12px;display:grid;place-items:center;font-size:1.6rem;color:var(--text)} 721body.menu-open{overflow:hidden;overscroll-behavior:none} 722@media (max-width:900px){.nav__burger{display:inline-flex}.nav__cta .nav__login{display:none}.nav__cta .btn--primary{display:none}} 723@media (min-width:901px){.mnav{display:none}} 724/* ===== shared motion vocabulary (IO-gated, reduced-motion + LCP safe) ===== */ 725@media (prefers-reduced-motion: no-preference){ 726 html.js [data-rise]{opacity:0;transform:translateY(38px);transition:opacity 1.7s var(--ease),transform 1.7s var(--ease),filter 1.7s var(--ease)} 727 html.js [data-rise="left"]{transform:translateX(-48px)} 728 html.js [data-rise="right"]{transform:translateX(48px)} 729 html.js [data-rise="scale"]{transform:translateY(28px) scale(.92)} 730 html.js [data-rise="blur"]{filter:blur(16px);opacity:0} 731 html.js [data-rise].in{opacity:1;transform:none;filter:none} 732 /* staggered children: cascade as the container reveals */ 733 html.js [data-rise] [data-stg]{opacity:0;transform:translateY(26px);transition:opacity 1.4s var(--ease),transform 1.4s var(--ease)} 734 html.js [data-rise].in [data-stg]{opacity:1;transform:none} 735 html.js [data-rise].in [data-stg]:nth-child(2){transition-delay:.14s} 736 html.js [data-rise].in [data-stg]:nth-child(3){transition-delay:.28s} 737 html.js [data-rise].in [data-stg]:nth-child(4){transition-delay:.42s} 738 html.js [data-rise].in [data-stg]:nth-child(5){transition-delay:.56s} 739 html.js [data-rise].in [data-stg]:nth-child(6){transition-delay:.70s} 740 html.js [data-rise].in [data-stg]:nth-child(7){transition-delay:.84s} 741 html.js [data-rise].in [data-stg]:nth-child(n+8){transition-delay:.98s} 742 /* subtle scroll parallax target (JS drives transform) */ 743 html.js [data-par]{will-change:transform} 744} 745/* ===== LNR â line-mask reveal (coffee-tech.com style): below-the-fold headings/paragraphs 746 split into lines that WIPE up from behind a mask (clip-path + translateY), staggered .1s/line, 747 1.6s power4-out. Mask wipe, not a fade. Engine: /assets/js/lnr.js (auto-inits on non-blog pages; 748 sets html.lnr only when motion allowed â reduced-motion / no-JS leave text fully visible). ===== */ 749:root{--lnr-ease:cubic-bezier(.25,1,.5,1)}.lnr-line,.lnr-w{font-size:inherit!important;color:inherit!important;letter-spacing:inherit!important} 750@media (prefers-reduced-motion: no-preference){ 751 html.lnr .lnr-hide{opacity:0} 752 html.lnr .lnr-line{display:block;transform:translateY(100%);opacity:0;clip-path:inset(0 0 100% 0);transition:transform 2.1s var(--lnr-ease),clip-path 2.1s var(--lnr-ease)} 753 html.lnr .lnr-in{opacity:1} 754 html.lnr .lnr-in .lnr-line{transform:none;opacity:1;clip-path:inset(0 -5% -30% 0)} 755 html.lnr [data-rise].lnr-nofade{opacity:1!important;transform:none!important;filter:none!important} 756 /* pre-paint arm: hide wipe-targets before first paint so above-the-fold text wipes on load with no 757 flash. Hero H1 (never listed) + hero/chrome subtrees stay visible â LCP-safe. Engine reveals 758 each target (adds .lnr-in) or clears it (.lnr-x). visibility keeps layout â no CLS. */ 759 html.lnr-arm :is(h2,h3,h4,h5,h6,p,li,blockquote,.eyebrow,.lead,figcaption):not(.lnr-in):not(.lnr-x):not
759(:is(.hero,.phero,[data-h],nav,.nav,footer,.footer,.growx,.clog,.mcar,.mbar,.hub-m,.csphere,.eco-hub,.scrim,.cap,[aria-hidden="true"]) *){opacity:0} 760} 761/* ===== Cinematic scroll scenes â Apple-style pinned / scrubbed timelines. 762 Driven by GSAP ScrollTrigger via /assets/js/cine.js, which adds html.cine-on ONLY after 763 GSAP loads AND motion is allowed. With no JS, reduced-motion, or a CDN failure the markup 764 degrades to an ordinary readable stack â nothing is ever hidden behind a transform. */ 765.cine{position:relative} 766.cine__beat{max-width:760px;margin-inline:auto} 767.cine[data-cine] .cine__beat+.cine__beat{margin-top:1.5em} 768.cine__layer--bg{display:none}/* decorative glow: only shown in cinematic mode */ 769html.cine-on .cine__pin{position:relative;min-height:100svh;display:grid;place-items:center;overflow:clip;isolation:isolate} 770html.cine-on .cine__layer{position:absolute;inset:0;display:grid;place-items:center;pointer-events:none;padding:max(96px,13vh) 22px 9vh} 771html.cine-on .cine__layer--top{align-items:start} 772html.cine-on .cine__layer--bg{z-index:1}html.cine-on .cine__layer--media{z-index:2}html.cine-on .cine__layer--fg{z-index:3} 773html.cine-on .cine__beat{grid-area:1/1;margin:0;width:min(760px,90vw);pointer-events:none} 774html.cine-on .cine__beat a,html.cine-on .cine__beat button{pointer-events:auto} 775html.cine-on [data-c]{will-change:transform,opacity,filter;backface-visibility:hidden} 776 777/* device frames (real UI) */ 778.dev{position:relative;border-radius:30px;padding:9px;background:linear-gradient(155deg,#222838,#0c1018); 779 box-shadow:0 48px 90px -38px rgba(8,20,60,.55),inset 0 0 0 1px rgba(255,255,255,.1),0 0 0 .5px rgba(0,0,0,.5)} 780.dev .s{position:relative;border-radius:22px;overflow:hidden;background:#0b0e16;aspect-ratio:1080/1920} 781.dev .s img{width:100%;height:100%;object-fit:cover;display:block} 782.dev--phone{border-radius:26px;padding:7px}.dev--phone .s{border-radius:19px} 783.dev--phone::before{content:"";position:absolute;z-index:3;top:7px;left:50%;transform:translateX(-50%);width:54px;height:15px;background:#0c1018;border-radius:0 0 11px 11px} 784/* product hero */ 785.phero{position:relative;padding:120px 0 40px;overflow:hidden} 786.phero__grid{display:grid;grid-template-columns:1.05fr .95fr;gap:48px;align-items:center} 787.phero__copy{max-width:560px} 788.phero h1{font-size:clamp(2.3rem,4.6vw,4rem);margin:.3em 0 .4em;letter-spacing:-.03em} 789.phero .lead{max-width:34ch} 790.phero__stage{position:relative;display:flex;justify-content:center;gap:18px;align-items:flex-end} 791.phero__stage .dev--kiosk{width:min(270px,58%)} 792.phero__stage .dev--phone{width:140px;margin-bottom:18px} 793@media(max-width:920px){.phero__grid{grid-template-columns:1fr;gap:34px}.phero{padding:104px 0 20px}} 794/* feature rows (alternating image/text) */ 795.featrow{display:grid;grid-template-columns:1fr 1fr;gap:clamp(28px,5vw,72px);align-items:center;padding:clamp(40px,6vw,80px) 0} 796.featrow:nth-child(even) .featrow__media{order:2} 797.featrow__copy h2{font-size:clamp(1.7rem,3vw,2.5rem);margin:.3em 0 .4em} 798.featrow__copy .lead{font-size:1.08rem} 799.featrow__list{list-style:none;margin-top:18px;display:grid;gap:10px} 800.featrow__list li{display:flex;gap:10px;align-items:flex-start;color:var(--text-2);font-weight:500} 801.featrow__list svg{width:20px;height:20px;color:var(--brand-text);flex:none;margin-top:2px} 802.featrow__media{position:relative;display:flex;justify-content:center} 803.featrow__media .dev--kiosk{width:min(280px,72%)} 804.featrow__media .shot{width:100%;border-radius:var(--r-lg);overflow:hidden;border:1px solid var(--glass-brd-soft);box-shadow:var(--shadow-lg)} 805.featrow__media .shot img{width:100%;display:block} 806/* min-width:0 lets grid tracks shrink below content width so copy wraps inside the 807 viewport on mobile instead of overflowing the right edge */ 808.featrow__copy,.featrow__media{min-width:0} 809@media(max-width:820px){.featrow{grid-template-columns:minmax(0,1fr);gap:26px}.featrow:nth-child(even) .featrow__media{order:0}} 810/* shared glass testimonial cards (used by demo + industry pages) */ 811.quotes{display:grid;grid-template-columns:repeat(2,1fr);gap:16px} 812@media(max-width:760px){.quotes{grid-template-columns:1fr}} 813.quote{background:var(--glass);border:1px solid var(--glass-brd-soft);border-radius:var(--r-lg);padding:26px 28px; 814 -webkit-backdrop-filter:var(--glass-blur);backdrop-filter:var(--glass-blur);box-shadow:var(--glass-hi)} 815.quote__stars{color:var(--blue-500);letter-spacing:2px;font-size:.86rem;margin-bottom:10px} 816.quote p{font-size:1.06rem;line-height:1.5;margin:0 0 14px;font-weight:500} 817.quote__by b{font-weight:600}.quote__by span{color:var(--text-3);font-size:.85rem;margin-left:8px} 818/* hardware lineup */ 819.hw{display:grid;grid-template-columns:repeat(4,1fr);gap:18px} 820.hwc{text-align:center;background:var(--glass);-webkit-backdrop-filter:var(--glass-blur);backdrop-filter:var(--glass-blur);border:1px solid var(--glass-brd-soft);border-radius:var(--r-lg);padding:22px;box-shadow:var(--glass-hi);transition:transform .4s var(--ease),box-shadow .4s} 821.hwc:hover{transform:translateY(-6px);box-shadow:var(--glass-hi),var(--shadow-lg)} 822.hwc__img{height:210px;display:grid;place-items:center;margin-bottom:14px} 823.hwc__img img{max-height:210px;width:auto;object-fit:contain;border-radius:14px;filter:drop-shadow(0 26px 36px rgba(10,30,80,.22))} 824.hwc b{font-size:1.02rem;font-weight:600}.hwc span{color:var(--text-3);font-size:.88rem} 825@media(max-width:820px){.hw{grid-template-columns:1fr 1fr}} 826/* stat tiles */ 827.stats{display:grid;grid-template-columns:repeat(4,1fr);gap:16px} 828@media(max-width:860px){.stats{grid-template-columns:1fr 1fr}} 829.stat{padding:26px;border-radius:var(--r-lg);background:var(--glass);-webkit-backdrop-filter:var(--glass-blur);backdrop-filter:var(--glass-blur);border:1px solid var(--glass-brd-soft);box-shadow:var(--glass-hi),var(--shadow)} 830.stat__n{font-family:var(--display);font-weight:700;font-size:clamp(2rem,3.4vw,2.8rem);line-height:1;letter-spacing:-.02em;font-variant-numeric:tabular-nums;color:var(--brand-text)} 831.stat__l{margin-top:10px;color:var(--text-2);font-size:.92rem;line-height:1.45}.stat__l b{color:var(--text);font-weight:600} 832/* big CTA */ 833.bigcta{position:relative;text-align:center;border-radius:var(--r-xl);padding:clamp(48px,8vw,92px) 24px;overflow:hidden;background:linear-gradient(135deg,var(--blue-600),var(--blue-800));color:#fff;box-shadow:var(--shadow-lg)} 834.bigcta::before{content:"";position:absolute;inset:0;background:radial-gradient(60% 120% at 80% 0%,rgba(120,160,255,.5),transparent 60%);pointer-events:none} 835.bigcta h2{color:#fff;position:relative}.bigcta p{color:rgba(255,255,255,.86);position:relative;margin:.5em auto 0;max-width:48ch} 836.bigcta .cta-row{position:relative;justify-content:center;margin-top:1.6em} 837.bigcta .btn--ghost{background:rgba(255,255,255,.14);color:#fff;border-color:rgba(255,255,255,.4)} 838.pbadge{display:inline-flex;align-items:center;gap:8px;font-family:var(--mono,var(--body));font-weight:700;font-size:.74rem;letter-spacing:.14em;text-transform:uppercase;color:#fff;background:linear-gradient(135deg,var(--blue-500),var(--blue-700));padding:.55em 1.05em;border-radius:var(--r-pill);box-shadow:0 10px 24px -10px var(--ring)} 839/* feature capability grid (shipped features from release notes) */ 840.fgrid{display:grid;grid-template-columns:repeat(4,1fr);gap:16px} 841.fgrid--3{grid-template-columns:repeat(3,1fr)} 842.fcard{background:var(--glass);border:1px solid var(--glass-brd-soft);border-radius:var(--r-lg);padding:24px; 843 -webkit-backdrop-filter:var(--glass-blur);backdrop-filter:var(--glass-blur);box-shadow:var(--glass-hi);transition:transform .4s var(--ease),box-shadow .4s} 844.fcard:hover{transform:translateY(-5px);box-shadow:var(--glass-hi),var(--shadow-lg)} 845.fcard__ic{width:42px;height:42px;border-radius:12px;display:grid;place-items:center;margin-bottom:14px; 846 background:linear-gradient(135deg,var(--blue-400,#3b82f6),var(--blue-600,#1d4ed8));box-shadow:0 10px 22px -10px rgba(47,93,255,.5)} 847.fcard__ic svg{width:21px;height:21px;color:#fff} 848.fcard b{display:block;font-size:1rem;font-weight:600;margin-bottom:.4em} 849.fcard span{color:var(--text-2);font-size:.9rem;line-height:1.5} 850.fcard small{display:inline-block;margin-top:.7em;font-size:.72rem;font-weight:700;letter-spacing:.04em;color:var(--brand-text);text-transform:uppercase} 851@media(max-width:980px){.fgrid,.fgrid--3{grid-template-columns:1fr 1fr}} 852@media(max-width:540px){.fgrid,.fgrid--3{grid-template-columns:1fr}} 853/* ===== progressive disclosure â supplementary copy stays out of the way until opened ===== 854 Markup: add .has-reveal to the card and wrap the hideable line as 855 <p class="reveal"><span>â¦</span></p>. Collapsed by default on EVERY device, so the phone 856 also shows less; opens on desktop hover, keyboard focus, or a tap on touch (.is-open is set 857 by the SCRIPTS handler, which also injects the .rv-plus tap affordance). */ 858.reveal{color:var(--text-2)} 859.has-reveal .reveal{display:grid;grid-template-rows:0fr;opacity:0;margin-block:0; 860 transition:grid-template-rows .42s var(--ease),opacity .3s var(--ease),margin .42s var(--ease)} 861.has-reveal .reveal>*{overflow:hidden;min-height:0;margin:0} 862.has-reveal:focus-within .reveal,.has-reveal.is-open .reveal{grid-template-rows:1fr;opacity:1;margin-block:.55em 0} 863@media (hover:hover) and (pointer:fine){.has-reveal:hover .reveal{grid-template-rows:1fr;opacity:1;margin-block:.55em 0}} 864/* the always-visible chips/specs row sits flush until the card opens */ 865.has-reveal .reveal+*{margin-top:0} 866/* touch tap affordance â a small + that rotates to à when the card is open (JS-injected, collision-safe real element) */ 867.rv-plus{display:none} 868@media (hover:none){ 869 .has-reveal[data-rv]{position:relative;cursor:pointer} 870 .has-reveal[data-rv]>.rv-plus{display:grid;place-items:center;position:absolute;top:10px;right:10px;width:22px;height:22px; 871 border-radius:50%;background:var(--glass-strong);border:1px solid var(--glass-brd-soft);color:var(--brand-text); 872 font:600 16px/1 var(--body);transition:transform .35s var(--ease);pointer-events:none;z-index:4} 873 .has-reveal[data-rv]>.rv-plus::before{content:"+"} 874 .has-reveal[data-rv].is-open>.rv-plus{transform:rotate(45deg)} 875} 876 877.hub-grid{display:grid;grid-template-columns:repeat(3,1fr);gap:clamp(18px,2.4vw,30px);margin-top:clamp(24px,3vw,40px)} 878@media(max-width:920px){.hub-grid{grid-template-columns:1fr 1fr}} 879@media(max-width:600px){.hub-grid{grid-template-columns:1fr}} 880.hub-card{display:flex;flex-direction:column;background:var(--surface);border:1px solid var(--line-2);border-radius:var(--r-lg);overflow:hidden;box-shadow:var(--shadow-sm);transition:transform .4s var(--ease),box-shadow .4s var(--ease),border-color .4s var(--ease)} 881.hub-card:hover{transform:translateY(-5px);box-shadow:var(--shadow);border-color:var(--line)}
882.hub-card__media{aspect-ratio:16/10;overflow:hidden;background:var(--bg-soft)} 883.hub-card__media img{width:100%;height:100%;object-fit:cover;display:block;transition:transform .6s var(--ease)} 884.hub-card:hover .hub-card__media img{transform:scale(1.04)} 885.hub-card__body{padding:18px 20px 22px;display:flex;flex-direction:column;gap:8px;flex:1} 886.hub-card__tag{font:800 .68rem/1 var(--body);letter-spacing:.12em;text-transform:uppercase;color:var(--brand-text)} 887.hub-card__h{font-family:var(--display);font-weight:600;font-size:1.08rem;line-height:1.22;letter-spacing:-.01em} 888.hub-card__h a{color:var(--text)}.hub-card__h a:hover{color:var(--brand-text)} 889.hub-card__meta{margin-top:auto;color:var(--text-3);font-size:.82rem} 890/* resources directory */ 891.hub-dir{display:grid;grid-template-columns:repeat(3,1fr);gap:clamp(16px,2vw,22px);margin-top:clamp(24px,3vw,40px)} 892@media(max-width:820px){.hub-dir{grid-template-columns:1fr 1fr}} 893@media(max-width:520px){.hub-dir{grid-template-columns:1fr}} 894.hub-dir__card{display:block;padding:26px 24px;background:var(--glass);border:1px solid var(--glass-brd-soft);border-radius:var(--r-lg);box-shadow:var(--glass-hi);transition:.3s var(--ease)} 895.hub-dir__card:hover{transform:translateY(-4px);border-color:var(--blue-300)} 896.hub-dir__card h3{font-family:var(--display);font-weight:600;font-size:1.15rem;margin-bottom:.35em;color:var(--text)} 897.hub-dir__card p{color:var(--text-2);font-size:.94rem;line-height:1.5} 898.hub-dir__card .arrow{color:var(--brand-text);font-weight:600;font-size:.9rem;margin-top:.7em;display:inline-block} 899 900</style>
901<script type="application/ld+json">{"@context":"https://schema.org","@graph":[{"@type":"Organization","@id":"https://infi.us/#org","name":"INFI","legalName":"Infinet LLC","alternateName":"INFI Restaurant Growth Platform","url":"https://infi.us/","logo":{"@type":"ImageObject","url":"https://infi.us/icon-512.png","width":512,"height":512},"image":"https://infi.us/og-default.png","description":"INFI adds self-ordering kiosks, commission-free online ordering, loyalty, marketing, and a live website on top of the POS a restaurant already runs.","slogan":"Stack growth on the POS you already run.","knowsAbout":["Self-ordering kiosks","Online ordering for restaurants","Restaurant loyalty programs","Restaurant marketing","Kitchen display systems","POS integration","Square","Toast","Clover"]},{"@type":"WebSite","@id":"https://infi.us/#website","url":"https://infi.us/","name":"INFI","publisher":{"@id":"https://infi.us/#org"},"inLanguage":"en-US"},{"@type":"WebPage","@id":"https://infi.us/news#webpage","url":"https://infi.us/news","name":"INFI News & Announcements â Restaurant Technology Updates","description":"The latest INFI news: funding, partnerships, trade shows and events, company milestones, and product announcements from across our restaurant self-ordering platform.","isPartOf":{"@id":"https://infi.us/#website"},"about":{"@id":"https://infi.us/#org"},"primaryImageOfPage":"https://infi.us/img/og/news.jpg?v=3","inLanguage":"en-US"}]}</script>
vendor: 1 bytes, line 901
901
902<script type="application/ld+json">{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https://infi.us/"},{"@type":"ListItem","position":2,"name":"INFI News & Announcements","item":"https://infi.us/news"}]}</script>
902 903</head> 904<body> 905<!-- Google Tag Manager (noscript) -->
vendor: 67 bytes, line 905
905<noscript><iframe src="https://www.googletagmanager.com/ns.html?id=
905GTM-5PRV2XG
vendor: 82 bytes, line 905
905" height="0" width="0" style="display:none;visibility:hidden"></iframe></noscript>
905<!-- End Google Tag Manager (noscript) --> 906<div class="amb" aria-hidden="true"><i class="amb__geo amb__g1"></i><i class="amb__geo amb__g2"></i><i class="amb__geo amb__g3"></i><i class="amb__ring"></i><i class="amb__beam amb__b1"></i><i class="amb__beam amb__b2"></i></div><style> 907.nav{top:36px} 908@media(max-width:680px){.nav{top:34px}} 909.fombar{position:fixed;top:0;left:0;right:0;z-index:92;display:block;text-decoration:none;color:#fff; 910 background:linear-gradient(90deg,#15259a 0%,#2f5dff 46%,#2aa0e6 100%)} 911.fombar__in{max-width:1180px;margin:0 auto;min-height:36px;display:flex;align-items:center;justify-content:center;gap:13px;padding:5px 18px;text-align:center;line-height:1.2} 912.fombar__tag{display:inline-flex;align-items:center;gap:7px;flex:none;font-family:var(--mono,var(--body));font-weight:700;letter-spacing:.1em;text-transform:uppercase;font-size:.66rem} 913.fombar__tag svg{width:13px;height:13px} 914.fombar__txt{font-size:.84rem;font-weight:500;opacity:.96} 915.fombar__txt b{font-weight:700} 916.fombar__cta{display:inline-flex;align-items:center;gap:5px;flex:none;font-weight:700;font-size:.8rem; 917 background:rgba(255,255,255,.16);padding:.26em .8em;border-radius:999px;border:1px solid rgba(255,255,255,.3)} 918.fombar__cta svg{width:13px;height:13px;transition:transform .3s ease} 919.fombar:hover .fombar__cta svg{transform:translateX(3px)} 920@media(max-width:680px){.fombar__in{min-height:34px;gap:9px}.fombar__txt{font-size:.78rem}.fombar__txt .long{display:none}} 921@media(max-width:430px){.fombar__tag span{display:none}.fombar__cta span{display:none}} 922</style> 923<a class="fombar" href="/feature" aria-label="Featured: INFI Connect"> 924 <span class="fombar__in"> 925 <span class="fombar__tag"><svg viewBox="0 0 24 24" fill="currentColor" aria-hidden="true"><path d="M12 2l2.4 7.2H22l-6.2 4.5 2.4 7.3L12 16.5l-6.2 4.4 2.4-7.2L2 9.2h7.6z"/></svg><span>Featured</span></span> 926 <span class="fombar__txt"><b>INFI Connect</b><span class="long"> â run your restaurant from your phone</span></span> 927 <span class="fombar__cta"><span>Explore</span><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.6" stroke-linecap="round" stroke-linejoin="round"><path d="M5 12h14M13 6l6 6-6 6"/></svg></span> 928 </span> 929</a> 930<header class="nav" id="nav"> 931 <div class="wrap nav__in"> 932 <a class="nav__logo" href="/" aria-label="INFI home"><img class="lg-l" src="/img/logo.webp" alt="INFI" width="71" height="23"><img class="lg-d" src="/img/logo-white.webp" alt="" aria-hidden="true" width="71" height="23"></a> 933 <nav class="nav__links" aria-label="Primary"> 934 <span class="nav__has"><a href="/product">Products â¾</a> 935 <div class="nav__drop nav__drop--groups"> 936 <a class="nav__ov" href="/product">Platform Overview</a> 937 <p class="nav__grp">Ordering</p> 938 <a href="/self-ordering-kiosks">Self-Ordering Kiosks</a> 939 <a href="/products/online-ordering">Online Ordering</a> 940 <a href="/products/mobile-app">Branded Mobile App</a> 941 <p class="nav__grp">Customer Engagement</p> 942 <a href="/products/loyalty">Loyalty & Rewards</a> 943 <a href="/products/display">Digital Menu Boards</a> 944 <p class="nav__grp">Web Presence</p> 945 <a href="/products/website-builder">Restaurant Websites</a> 946 <a href="/products/marketing">Online Presence & Growth</a> 947 <p class="nav__grp">Operations & Integrations</p> 948 <a href="/products/kitchen">Kitchen Display System</a> 949 <a href="/products/connect">POS Integration</a> 950 </div> 951 </span> 952 <span class="nav__has"><a href="/integrations">Integrations â¾</a> 953 <div class="nav__drop"> 954 <a href="/integrations/square">Square</a> 955 <a href="/integrations/toast">Toast</a> 956 <a href="/integrations/clover">Clover</a> 957 <a href="/integrations/lightspeed">Lightspeed</a> 958 <a href="/integrations">All integrations â</a> 959 </div> 960 </span> 961 <span class="nav__has"><button>Industries â¾</button> 962 <div class="nav__drop"> 963 <a href="/qsrs-fast-casual">QSR & Fast Casual</a> 964 <a href="/boba-beverage">Boba & Beverage</a> 965 <a href="/coffee-shops">Coffee Shops</a> 966 <a href="/food-halls-malls">Food Halls & Malls</a> 967 <a href="/industries/venues">Venues & Arenas</a> 968 <a href="/industries">All industries â</a> 969 </div> 970 </span> 971 <a href="/platform">Platform</a> 972 <a href="/pricing">Pricing</a> 973 <a href="/blog">Blog</a>
974 <span class="nav__has"><button>Company â¾</button> 975 <div class="nav__drop"> 976 <a href="/about">About INFI</a> 977 <a href="/case-studies">Case Studies</a> 978 <a href="/our-team">Our Team</a> 979 <a href="/partners">Partners</a> 980 <a href="/competitor-comparison">Competitor Comparison</a> 981 <a href="/contact-us">Contact us</a> 982 </div> 983 </span> 984 </nav> 985 <div class="nav__cta"> 986 <span class="nav__has nav__has--login"> 987 <button class="nav__login" aria-haspopup="true" aria-expanded="false">Sign in â¾</button> 988 <div class="nav__drop nav__drop--right"> 989 <a href="https://prod.orderwithinfi.com/merchant-portal/auth/sign-in">New INFI Console <small>Current merchant portal</small></a> 990 <a href="https://infi-console.firebaseapp.com/auth/login">INFI Console <small>Legacy console</small></a> 991 </div> 992 </span> 993 <a class="btn btn--primary" href="/demo">Book a Demo</a> 994 </div> 995 <button class="nav__burger" id="burger" aria-label="Open menu" aria-expanded="false"><span></span></button> 996 </div> 997</header> 998<nav class="mnav" id="mnav" aria-label="Mobile"> 999 <button class="mnav__x" id="mnavx" aria-label="Close menu">Ã</button> 1000 <a href="/product">Explore in 3D <small>The whole INFI platform in one interactive scene</small></a> 1001 <a href="/feature" style="color:var(--brand-text)">⦠Featured <small>INFI Connect â run your restaurant from your phone</small></a> 1002 <p class="mnav__grp">Ordering</p> 1003 <a href="/self-ordering-kiosks">Self-Ordering Kiosks <small>Floor-stand & countertop</small></a> 1004 <a href="/products/online-ordering">Online Ordering <small>Web & QR</small></a> 1005 <a href="/products/mobile-app">Branded Mobile App <small>iOS & Android</small></a> 1006 <p class="mnav__grp">Customer Engagement</p> 1007 <a href="/products/loyalty">Loyalty & Rewards <small>Customer profiles</small></a> 1008 <a href="/products/display">Digital Menu Boards <small>Cloud-managed screens</small></a> 1009 <p class="mnav__grp">Web Presence</p> 1010 <a href="/products/website-builder">Restaurant Websites <small>Live menu & SEO</small></a> 1011 <a href="/products/marketing">Online Presence & Growth <small>Google, reviews & SEO</small></a> 1012 <p class="mnav__grp">Operations & Integrations</p> 1013 <a href="/products/kitchen">Kitchen Display System <small>Order routing</small></a> 1014 <a href="/products/connect">POS Integration <small>Square, Toast, Clover, Lightspeed</small></a> 1015 <a href="/integrations">All Integrations <small>Square · Toast · Clover · Lightspeed</small></a> 1016 <a href="/platform">Platform</a><a href="/industries">Industries</a><a href="/pricing">Pricing</a><a href="/blog">Blog</a> 1017 <a href="/about">About <small>The company & team</small></a> 1018 <a href="/case-studies">Case Studies <small>Real operator results</small></a> 1019 <a href="/our-team">Our Team <small>The people behind INFI</small></a> 1020 <a href="/partners">Partners <small>Reseller, referral & integration</small></a> 1021 <a href="/competitor-comparison">Competitor Comparison <small>INFI vs the POS</small></a> 1022 <a href="/contact-us">Contact <small>Talk to the team</small></a> 1023 <a href="https://prod.orderwithinfi.com/merchant-portal/auth/sign-in">Sign in <small>New INFI Console</small></a> 1024 <a href="https://infi-console.firebaseapp.com/auth/login">Legacy Console <small>infi-console</small></a> 1025 <a class="btn btn--primary btn--lg" href="/demo">Book a Demo</a> 1026 <div class="themebox mnav__theme"><span class="themebox__lbl">Appearance</span><div class="themeseg" role="group" aria-label="Color theme"><button type="button" data-theme-set="auto">Auto</button><button type="button" data-theme-set="light">Light</button><button type="button" data-theme-set="dark">Dark</button></div></div> 1027</nav> 1028<main id="main"> 1029 1030<section class="phero"><div class="wrap" style="max-width:820px"> 1031 <div data-rise> 1032 <span class="pbadge">News</span> 1033 <h1 class="h-display" style="margin:.3em 0 .4em">Latest news & <span class="grad">announcements</span>.</h1> 1034 <p class="lead">Funding, partnerships, trade shows, and company milestones from INFI. For how-to guides and case studies, browse the full blog.</p> 1035 <div class="cta-row" data-rise> 1036 <a class="btn btn--primary btn--lg" href="/blog">All articles</a> 1037 <a class="btn btn--ghost btn--lg" href="/newsletter">Product updates</a> 1038 </div> 1039 </div> 1040</div></section> 1041 1042<section class="section section--tight"><div class="wrap"> 1043 <h2 class="sr-only">News articles</h2>
1044 <div class="hub-grid"> 1045 <article class="hub-card"> 1046 <a class="hub-card__media" href="/meet-the-infi-team-at-upcoming-shows-in-dallas-and-chicago" tabindex="-1" aria-hidden="true"><img src="/img/blog/meet-the-infi-team-at-upcoming-shows-in-dallas-and-chicago.webp" srcset="/img/blog/meet-the-infi-team-at-upcoming-shows-in-dallas-and-chicago-480.webp 480w, /img/blog/meet-the-infi-team-at-upcoming-shows-in-dallas-and-chicago-960.webp 960w, /img/blog/meet-the-infi-team-at-upcoming-shows-in-dallas-and-chicago.webp 1280w" sizes="(max-width:820px) 90vw, 360px" alt="" loading="lazy" decoding="async"></a> 1047 <div class="hub-card__body"> 1048 <div class="hub-card__tag">News</div> 1049 <h3 class="hub-card__h"><a href="/meet-the-infi-team-at-upcoming-shows-in-dallas-and-chicago">Meet the INFI Team at Upcoming Shows in Dallas and Chicago</a></h3> 1050 <div class="hub-card__meta">Mar 16, 2026 · 1 min read</div> 1051 </div> 1052 </article> 1053 <article class="hub-card"> 1054 <a class="hub-card__media" href="/infi-road-show-2026" tabindex="-1" aria-hidden="true"><img src="/img/blog/infi-road-show-2026.webp" srcset="/img/blog/infi-road-show-2026-480.webp 480w, /img/blog/infi-road-show-2026-960.webp 960w, /img/blog/infi-road-show-2026.webp 1280w" sizes="(max-width:820px) 90vw, 360px" alt="" loading="lazy" decoding="async"></a> 1055 <div class="hub-card__body"> 1056 <div class="hub-card__tag">News</div> 1057 <h3 class="hub-card__h"><a href="/infi-road-show-2026">INFI Kiosk in Person at These Upcoming Trade Shows</a></h3> 1058 <div class="hub-card__meta">Feb 16, 2026 · 2 min read</div> 1059 </div> 1060 </article> 1061 <article class="hub-card"> 1062 <a class="hub-card__media" href="/infi-automated-retail-kiosk-innovation-2025" tabindex="-1" aria-hidden="true"><img src="/img/blog/infi-automated-retail-kiosk-innovation-2025.webp" srcset="/img/blog/infi-automated-retail-kiosk-innovation-2025-480.webp 480w, /img/blog/infi-automated-retail-kiosk-innovation-2025-960.webp 960w, /img/blog/infi-automated-retail-kiosk-innovation-2025.webp 1280w" sizes="(max-width:820px) 90vw, 360px" alt="" loading="lazy" decoding="async"></a> 1063 <div class="hub-card__body"> 1064 <div class="hub-card__tag">News</div> 1065 <h3 class="hub-card__h"><a href="/infi-automated-retail-kiosk-innovation-2025">INFI at the Automated Retail & Kiosk Innovation Show</a></h3> 1066 <div class="hub-card__meta">Dec 3, 2025 · 2 min read</div> 1067 </div> 1068 </article> 1069 <article class="hub-card"> 1070 <a class="hub-card__media" href="/infi-q4-2025-product-updates-enhancements" tabindex="-1" aria-hidden="true"><img src="/img/blog/infi-q4-2025-product-updates-enhancements.webp" srcset="/img/blog/infi-q4-2025-product-updates-enhancements-480.webp 480w, /img/blog/infi-q4-2025-product-updates-enhancements-960.webp 960w, /img/blog/infi-q4-2025-product-updates-enhancements.webp 1280w" sizes="(max-width:820px) 90vw, 360px" alt="" loading="lazy" decoding="async"></a> 1071 <div class="hub-card__body"> 1072 <div class="hub-card__tag">News</div> 1073 <h3 class="hub-card__h"><a href="/infi-q4-2025-product-updates-enhancements">INFI Q4 2025 Product Updates & Enhancements</a></h3> 1074 <div class="hub-card__meta">Nov 26, 2025 · 4 min read</div> 1075 </div> 1076 </article> 1077 <article class="hub-card"> 1078 <a class="hub-card__media" href="/august-product-release-notes" tabindex="-1" aria-hidden="true"><img src="/img/blog/august-product-release-notes.webp" srcset="/img/blog/august-product-release-notes-480.webp 480w, /img/blog/august-product-release-notes-960.webp 960w, /img/blog/august-product-release-notes.webp 1280w" sizes="(max-width:820px) 90vw, 360px" alt="" loading="lazy" decoding="async"></a> 1079 <div class="hub-card__body"> 1080 <div class="hub-card__tag">News</div> 1081 <h3 class="hub-card__h"><a href="/august-product-release-notes">August Product Release Notes</a></h3> 1082 <div class="hub-card__meta">Nov 9, 2025 · 1 min read</div> 1083 </div> 1084 </article> 1085 <article class="hub-card"> 1086 <a class="hub-card__media" href="/infi-partners-with-lightspeed-to-revolutionize-self-service-kiosk-solutions" tabindex="-1" aria-hidden="true"><img src="/img/blog/infi-partners-with-lightspeed-to-revolutionize-self-service-kiosk-solutions.webp" srcset="/img/blog/infi-partners-with-lightspeed-to-revolutionize-self-service-kiosk-solutions-480.webp 480w, /img/blog/infi-partners-with-lightspeed-to-revolutionize-self-service-kiosk-solutions-960.webp 960w, /img/blog/infi-partners-with-lightspeed-to-revolutionize-self-service-kiosk-solutions.webp 1280w" sizes="(max-width:820px) 90vw, 360px" alt="" loading="lazy" decoding="async"></a> 1087 <div class="hub-card__body"> 1088 <div class="hub-card__tag">News</div> 1089 <h3 class="hub-card__h"><a href="/infi-partners-with-lightspeed-to-revolutionize-self-service-kiosk-solutions">
1089INFI Partners with Lightspeed to Revolutionize Self-Service Kiosk Solutions</a></h3> 1090 <div class="hub-card__meta">Nov 9, 2025 · 2 min read</div> 1091 </div> 1092 </article> 1093 <article class="hub-card"> 1094 <a class="hub-card__media" href="/infi-raises-12-million-to-revolutionize-self-service-technology" tabindex="-1" aria-hidden="true"><img src="/img/blog/infi-raises-12-million-to-revolutionize-self-service-technology.webp" srcset="/img/blog/infi-raises-12-million-to-revolutionize-self-service-technology-480.webp 480w, /img/blog/infi-raises-12-million-to-revolutionize-self-service-technology-960.webp 960w, /img/blog/infi-raises-12-million-to-revolutionize-self-service-technology.webp 1280w" sizes="(max-width:820px) 90vw, 360px" alt="" loading="lazy" decoding="async"></a> 1095 <div class="hub-card__body"> 1096 <div class="hub-card__tag">News</div> 1097 <h3 class="hub-card__h"><a href="/infi-raises-12-million-to-revolutionize-self-service-technology">INFI Raises $12 Million to Revolutionize Self-Service Technology</a></h3> 1098 <div class="hub-card__meta">Nov 9, 2025 · 1 min read</div> 1099 </div> 1100 </article> 1101 <article class="hub-card"> 1102 <a class="hub-card__media" href="/november-product-release-notes" tabindex="-1" aria-hidden="true"><img src="/img/blog/november-product-release-notes.webp" srcset="/img/blog/november-product-release-notes-480.webp 480w, /img/blog/november-product-release-notes-960.webp 960w, /img/blog/november-product-release-notes.webp 1280w" sizes="(max-width:820px) 90vw, 360px" alt="" loading="lazy" decoding="async"></a> 1103 <div class="hub-card__body"> 1104 <div class="hub-card__tag">News</div> 1105 <h3 class="hub-card__h"><a href="/november-product-release-notes">November Product Release Notes</a></h3> 1106 <div class="hub-card__meta">Nov 9, 2025 · 1 min read</div> 1107 </div> 1108 </article> 1109 <article class="hub-card"> 1110 <a class="hub-card__media" href="/october-product-release-notes" tabindex="-1" aria-hidden="true"><img src="/img/blog/october-product-release-notes.webp" srcset="/img/blog/october-product-release-notes-480.webp 480w, /img/blog/october-product-release-notes-960.webp 960w, /img/blog/october-product-release-notes.webp 1280w" sizes="(max-width:820px) 90vw, 360px" alt="" loading="lazy" decoding="async"></a> 1111 <div class="hub-card__body"> 1112 <div class="hub-card__tag">News</div> 1113 <h3 class="hub-card__h"><a href="/october-product-release-notes">October Product Release Notes</a></h3> 1114 <div class="hub-card__meta">Nov 9, 2025 · 1 min read</div> 1115 </div> 1116 </article> 1117 <article class="hub-card"> 1118 <a class="hub-card__media" href="/september-product-release-notes" tabindex="-1" aria-hidden="true"><img src="/img/blog/september-product-release-notes.webp" srcset="/img/blog/september-product-release-notes-480.webp 480w, /img/blog/september-product-release-notes-960.webp 960w, /img/blog/september-product-release-notes.webp 1280w" sizes="(max-width:820px) 90vw, 360px" alt="" loading="lazy" decoding="async"></a> 1119 <div class="hub-card__body"> 1120 <div class="hub-card__tag">News</div> 1121 <h3 class="hub-card__h"><a href="/september-product-release-notes">September Product Release Notes</a></h3> 1122 <div class="hub-card__meta">Nov 9, 2025 · 1 min read</div> 1123 </div> 1124 </article> 1125 <article class="hub-card"> 1126 <a class="hub-card__media" href="/7-key-takeaways-from-infinets-webinar-with-a-former-panera-vp" tabindex="-1" aria-hidden="true"><img src="/img/blog/7-key-takeaways-from-infinets-webinar-with-a-former-panera-vp.webp" srcset="/img/blog/7-key-takeaways-from-infinets-webinar-with-a-former-panera-vp-480.webp 480w, /img/blog/7-key-takeaways-from-infinets-webinar-with-a-former-panera-vp-960.webp 960w, /img/blog/7-key-takeaways-from-infinets-webinar-with-a-former-panera-vp.webp 1280w" sizes="(max-width:820px) 90vw, 360px" alt="" loading="lazy" decoding="async"></a> 1127 <div class="hub-card__body"> 1128 <div class="hub-card__tag">News</div> 1129 <h3 class="hub-card__h"><a href="/7-key-takeaways-from-infinets-webinar-with-a-former-panera-vp">7 Key Takeaways From INFINETâs Webinar With a Former Panera VP</a></h3> 1130 <div class="hub-card__meta">Nov 8, 2025 · 4 min read</div> 1131 </div> 1132 </article> 1133 <article class="hub-card"> 1134 <a class="hub-card__media" href="/startup-essentials" tabindex="-1" aria-hidden="true"><img src="/img/blog/startup-essentials.webp" srcset="/img/blog/startup-essentials-480.webp 480w, /img/blog/startup-essentials-960.webp 960w, /img/blog/startup-essentials.webp 1280w" sizes="(max-width:820px) 90vw, 360px" alt="" loading="lazy" decoding="async"></a> 1135 <div class="hub-card__body"> 1136 <div class="hub-card__tag">News</div> 1137 <h3 class="hub-card__h"><a href="/startup-essentials">Find Your Market First - Startup Essentials</a></h3> 1138 <div class="hub-card__meta">Nov 8, 2025 · 12 min read</div> 1139 </div> 1140 </article> 1141 <article class="hub-card"> 1142 <a class="hub-card__media" href="/infi-expands-to-boston-indianapolis" tabindex="-1" aria-hidden="true"><img src="/img/blog/infi-expands-to-boston-indianapolis.webp" srcset="/img/blog/infi-expands-to-boston-indianapolis-480.webp 480w, /img/blog/infi-expands-to-boston-indianapolis-960.webp 960w, /img/blog/infi-expands-to-boston-indianapolis.webp 1280w" sizes="(max-width:820px) 90vw, 360px" alt="" loading="lazy" decoding="async"></a> 1143 <div class="hub-card__body"> 1144 <div class="hub-card__tag">News</div> 1145 <h3 class="hub-card__h"><a href="/infi-expands-to-boston-indianapolis">Infi Expands to Boston & Indianapolis</a></h3> 1146 <div class="hub-card__meta">Nov 8, 2025 · 1 min read</div> 1147 </div> 1148 </article> 1149 <article class="hub-card"> 1150 <a class="hub-card__media" href="/july-product-release-notes" tabindex="-1" aria-hidden="true"><img src="/img/blog/july-product-release-notes.webp" srcset="/img/blog/july-product-release-notes-480.webp 480w, /img/blog/july-product-release-notes-960.webp 960w, /img/blog/july-product-release-notes.webp 1280w" sizes="(max-width:820px) 90vw, 360px" alt="" loading="lazy" decoding="async"></a> 1151 <div class="hub-card__body"> 1152 <div class="hub-card__tag">News</div> 1153 <h3 class="hub-card__h"><a href="/july-product-release-notes">July Product Release Notes</a></h3> 1154 <div class="hub-card__meta">Nov 8, 2025 · 1 min read</div> 1155 </div> 1156 </article> 1157 <article class="hub-card"> 1158 <a class="hub-card__media" href="/miller-ip-law-podcast" tabindex="-1" aria-hidden="true"><img src="/img/blog/miller-ip-law-podcast.webp" srcset="/img/blog/miller-ip-law-podcast-480.webp 480w, /img/blog/miller-ip-law-podcast-960.webp 960w, /img/blog/miller-ip-law-podcast.webp 1280w" sizes="(max-width:820px) 90vw, 360px" alt="" loading="lazy" decoding="async"></a> 1159 <div class="hub-card__body"> 1160 <div class="hub-card__tag">News</div> 1161 <h3 class="hub-card__h"><a href="/miller-ip-law-podcast">Time Is Valuable - INFI Appears on the Miller IP Law Podcast</a></h3> 1162 <div class="hub-card__meta">Nov 8, 2025 · 16 min read</div> 1163 </div> 1164 </article></div> 1165</div></section> 1166</main> 1167<footer class="foot"> 1168 <div class="wrap"> 1169 <div class="foot__grid"> 1170 <div class="foot__brand"> 1171 <a class="nav__logo" href="/" aria-label="INFI home"><img src="/img/logo-white.webp" alt="INFI" width="92" height="30" style="height:30px"></a> 1172 <p class="foot__tag">The Restaurant Growth Platform. Add ordering, loyalty, marketing & a live website on top of the POS you already run.</p> 1173 <div class="themebox" style="margin-top:18px"><span class="themebox__lbl">Appearance</span><div class="themeseg" role="group" aria-label="Color theme"><button type="button" data-theme-set="auto">Auto</button><button type="button" data-theme-set="light">Light</button><button type="button" data-theme-set="dark">Dark</button></div></div> 1174 </div> 1175 <div><p class="foot__h" role="presentation">Products</p><a href="/self-ordering-kiosks">Self-Ordering Kiosks</a><a href="/products/online-ordering">Online Ordering</a><a href="/products/mobile-app">Branded Mobile App</a><a href="/products/connect">POS Integration</a><a href="/products/kitchen">Kitchen Display System</a><a href="/products/website-builder">Restaurant Websites</a><a href="/products/marketing">Online Presence & Growth</a><a href="/products/loyalty">Loyalty & Rewards</a><a href="/products/display">Digital Menu Boards</a></div> 1176 <div><p class="foot__h" role="presentation">Industries</p><a href="/qsrs-fast-casual">QSR & Fast Casual</a><a href="/boba-beverage">Boba & Beverage</a><a href="/coffee-shops">Coffee Shops</a><a href="/food-halls-malls">Food Halls</a><a href="/industries/venues">Venues & Arenas</a><a href="/industries">All industries</a></div> 1177 <div><p class="foot__h" role="presentation">Company</p><a href="/about">About</a><a href="/our-team">Our Team</a><a href="/case-studies">Case Studies</a><a href="/partners">Partners</a><a href="/referrals">Referrals</a><a href="/competitor-comparison">Competitor Comparison</a><a href="/contact-us">Contact</a><a href="/premium-support">Premium Support</a><a href="https://support.infi.us/hc/en-us" target="_blank" rel="noopener">Help Center</a><a href="/blog">Blog</a><a href="/news">News</a><a href="/resources">Resources</a><a href="/newsletter">What's New</a><a href="/downloads">Downloads</a></div> 1178 </div> 1179 <div class="foot__bar"><span>© 2026 INFI. At your service.</span><span class="foot__legal"><a href="/general-terms-and-conditions">Terms & Conditions</a><a href="/privacy-policy">Privacy Policy</a></span><span>Square · Toast · Clover · Lightspeed · HungerRush</span></div> 1180 </div> 1181</footer>
1181<script> 1182document.documentElement.classList.add('js'); 1183var nav=document.getElementById('nav');var onS=function(){nav.classList.toggle('is-stuck',scrollY>20)};onS();addEventListener('scroll',onS,{passive:true}); 1184var burger=document.getElementById('burger'),mnav=document.getElementById('mnav'),mnavx=document.getElementById('mnavx'); 1185function setMenu(o){mnav.classList.toggle('open',o);document.body.classList.toggle('menu-open',o);burger.setAttribute('aria-expanded',o)} 1186burger.addEventListener('click',function(){setMenu(!mnav.classList.contains('open'))});mnavx.addEventListener('click',function(){setMenu(false)}); 1187mnav.querySelectorAll('a').forEach(function(a){a.addEventListener('click',function(){setMenu(false)})}); 1188var rm=matchMedia('(prefers-reduced-motion: reduce)').matches; 1189if(!rm){var io=new IntersectionObserver(function(es){es.forEach(function(e){if(e.isIntersecting){e.target.classList.add('in');io.unobserve(e.target)}})},{rootMargin:'0px 0px -8% 0px'}); 1190/* Auto-reveal: give long-form body/prose text (blog articles etc.) the SAME unified rise as the 1191 curated [data-rise] sections, so every page's text shares one entrance. Only stamps top-level 1192 blocks that are below the fold at load â no flash, LCP-safe; skips anything already animated. */ 1193var _vh=innerHeight||document.documentElement.clientHeight; 1194[].forEach.call(document.querySelectorAll('.post__body>*,.prose>*,.legal>*:not(ol):not(ul),.legal>ol>li,.legal>ul>li'),function(el){ 1195 var t=el.tagName;if(t==='SCRIPT'||t==='STYLE'||t==='BR'||t==='HR')return; 1196 if(el.hasAttribute('data-rise')||el.closest('[data-rise],[data-cine],[data-c]'))return; 1197 if(el.getBoundingClientRect().top>_vh*0.86)el.setAttribute('data-rise',''); 1198}); 1199document.querySelectorAll('[data-rise]').forEach(function(el){io.observe(el)});} 1200if(!rm){function cu(el){var t=+el.dataset.count,pre=el.dataset.prefix||'',suf=el.dataset.suffix||'',s=null,dur=1400;function st(ts){if(!s)s=ts;var p=Math.min((ts-s)/dur,1),e=1-Math.pow(1-p,3),v=Math.round(t*e);el.textContent=pre+v.toLocaleString()+suf;if(p<1)requestAnimationFrame(st)}requestAnimationFrame(st)} 1201var cio=new IntersectionObserver(function(es){es.forEach(function(e){if(e.isIntersecting){cu(e.target);cio.unobserve(e.target)}})},{threshold:.6});document.querySelectorAll('[data-count]').forEach(function(el){cio.observe(el)});} 1202if(!rm){var P=[].slice.call(document.querySelectorAll('[data-par]'));if(P.length){var tk=0;function pf(){tk=0;var vh=innerHeight;for(var i=0;i<P.length;i++){var el=P[i],r=el.getBoundingClientRect(),c=(r.top+r.height/2-vh/2)/vh,sp=parseFloat(el.dataset.par)||.1;el.style.transform='translate3d(0,'+(c*sp*-72).toFixed(1)+'px,0)'}}addEventListener('scroll',function(){if(!tk){tk=1;requestAnimationFrame(pf)}},{passive:true});addEventListener('resize',pf,{passive:true});pf()}} 1203(function(){function st(m){if(m==='light'||m==='dark'){document.documentElement.setAttribute('data-theme',m)}else{m='auto';document.documentElement.removeAttribute('data-theme')}try{m==='auto'?localStorage.removeItem('infi-theme'):localStorage.setItem('infi-theme',m)}catch(e){}document.querySelectorAll('[data-theme-set]').forEach(function(b){b.setAttribute('aria-pressed',b.getAttribute('data-theme-set')===m)})}var s;try{s=localStorage.getItem('infi-theme')}catch(e){}var cur=(s==='light'||s==='dark')?s:'auto';document.querySelectorAll('[data-theme-set]').forEach(function(b){b.setAttribute('aria-pressed',b.getAttribute('data-theme-set')===cur);b.addEventListener('click',function(){st(b.getAttribute('data-theme-set'))})})})(); 1204/* ===== Capability Sphere â rotating keyword constellation + click-to-read detail ===== */ 1205(function(){ 1206 function ang(d){d%=2*Math.PI;if(d>Math.PI)d-=2*Math.PI;if(d<-Math.PI)d+=2*Math.PI;return d;} 1207 [].forEach.call(document.querySelectorAll('[data-csphere]'),function(orb){ 1208 var tags=[].slice.call(orb.querySelectorAll('.csphere__tag')),n=tags.length;if(!n)return; 1209 var wrap=orb.closest('.csphere__wrap'),cards=wrap?[].slice.call(wrap.querySelectorAll('.csphere__card')):[]; 1210 var pts=tags.map(function(_,i){var y=1-(i+0.5)/n*2,r=Math.sqrt(Math.max(0,1-y*y)),th=Math.PI*(3-Math.sqrt(5))*i;return{x:Math.cos(th)*r,y:y,z:Math.sin(th)*r};}); 1211 var ay=0.3,ax=-0.2,vy=0.0016,iy=0,ix=0,hover=false,drag=false,lx=0,ly=0,moved=0,focus=0,tay=0,tax=0,R=10,raf=0; 1212 function size(){R=orb.clientWidth*0.34;}size();addEventListener('resize',size,{passive:true}); 1213 function rm(){return matchMedia('(prefers-reduced-motion: reduce)').matches;} 1214 function frame(now){ 1215 if(!drag){ 1216 if(now<focus){ay+=(tay-ay)*0.12;ax+=(tax-ax)*0.12;} 1217 else{ay+=iy;ax+=ix;iy*=0.93;ix*=0.93;if(!hover&&!rm())ay+=vy;if(!hover&&Math.abs(ix)<0.0004)ax+=(-0.18-ax)*0.02;} 1218 } 1219 var cy=Math.cos(ay),sy=Math.sin(ay),cx=Math.cos(ax),sx=Math.sin(ax),i,p; 1220 for(i=0;i<n;i++){p=pts[i]; 1221 var x1=p.x*cy+p.z*sy,z1=-p.x*sy+p.z*cy,y1=p.y; 1222 var y2=y1*cx-z1*sx,z2=y1*sx+z1*cx,x2=x1; 1223 var sc=0.6+(z2+1)*0.33,op=0.24+(z2+1)*0.38,st=tags[i].style; 1224 st.transform='translate(-50%,-50%) translate3d('+(x2*R).toFixed(1)+'px,'+(y2*R).toFixed(1)+'px,0) scale('+sc.toFixed(3)+')'; 1225 st.opacity=op.toFixed(3);st.zIndex=((z2+1)*100)|0;st.filter=z2<0?'blur('+(-z2*1.3).toFixed(2)+'px)':'none';st.pointerEvents=z2<-0.08?'none':'auto'; 1226 } 1227 } 1228 function loop(t){frame(t||0);raf=requestAnimationFrame(loop);} 1229 function pick(i,spin){
1230 tags.forEach(function(t,k){var on=k===i;t.classList.toggle('is-sel',on);t.setAttribute('aria-pressed',on?'true':'false');}); 1231 cards.forEach(function(c,k){var on=k===i;c.classList.toggle('is-active',on);if(on)c.removeAttribute('hidden');else c.setAttribute('hidden','');}); 1232 if(spin){var p=pts[i],r=Math.sqrt(p.x*p.x+p.z*p.z),ty=Math.atan2(-p.x,p.z),tx=Math.atan2(p.y,r); 1233 if(rm()){ay=ty;ax=tx;frame(1e12);}else{tay=ay+ang(ty-ay);tax=tx;focus=performance.now()+1100;iy=ix=0;}} 1234 } 1235 tags.forEach(function(t,i){ 1236 t.addEventListener('click',function(){if(moved)return;pick(i,true);}); 1237 }); 1238 orb.addEventListener('pointerdown',function(e){drag=true;moved=0;lx=e.clientX;ly=e.clientY;focus=0;}); 1239 orb.addEventListener('pointermove',function(e){if(!drag)return;var dx=e.clientX-lx,dy=e.clientY-ly;lx=e.clientX;ly=e.clientY;if(Math.abs(dx)+Math.abs(dy)>3){if(!moved){try{orb.setPointerCapture(e.pointerId)}catch(_){}}moved=1;}ay+=dx*0.006;ax=Math.max(-1.25,Math.min(1.25,ax+dy*0.006));iy=dx*0.006;ix=dy*0.006;if(rm())frame(1e12);}); 1240 function up(){drag=false;setTimeout(function(){moved=0;},40);} 1241 orb.addEventListener('pointerup',up);orb.addEventListener('pointercancel',up); 1242 orb.addEventListener('mouseenter',function(){hover=true;});orb.addEventListener('mouseleave',function(){hover=false;}); 1243 pick(0,false);frame(0); 1244 if('IntersectionObserver' in window){ 1245 var io=new IntersectionObserver(function(es){es.forEach(function(e){ 1246 if(e.isIntersecting){if(!raf&&!rm())raf=requestAnimationFrame(loop);} 1247 else if(raf){cancelAnimationFrame(raf);raf=0;} 1248 });},{rootMargin:'140px'}); 1249 io.observe(orb); 1250 } else if(!rm())raf=requestAnimationFrame(loop); 1251 }); 1252})(); 1253/* ===== reveal on touch: tap a .has-reveal card to expand its hidden detail (pointer devices keep hover) ===== */ 1254(function(){ 1255 if(matchMedia('(hover: hover) and (pointer: fine)').matches)return; 1256 [].forEach.call(document.querySelectorAll('.has-reveal'),function(c){ 1257 if(!c.querySelector('.reveal'))return; 1258 if(c.tagName==='A'||c.closest('a')){c.classList.add('is-open');return;} /* link cards navigate on tap â just show the detail */ 1259 c.setAttribute('data-rv',''); 1260 var s=document.createElement('span');s.className='rv-plus';s.setAttribute('aria-hidden','true');c.appendChild(s); 1261 /* Cards that hold their own controls (download links, buttons) must NOT be role=button 1262 â that would nest interactive controls. Keep tap-to-open, but leave them role-less 1263 and not focusable as a widget (their inner controls stay the real tab stops). */ 1264 if(c.querySelector('a,button,input,select,textarea,[tabindex],[role="button"],[role="link"]')){ 1265 c.removeAttribute('tabindex'); 1266 c.addEventListener('click',function(e){if(e.target.closest('a,button,input,select,textarea,label'))return;c.classList.toggle('is-open');}); 1267 return; 1268 } 1269 c.setAttribute('role','button');c.setAttribute('tabindex','0');c.setAttribute('aria-expanded','false'); 1270 c.addEventListener('click',function(e){if(e.target.closest('a,button'))return;var o=c.classList.toggle('is-open');c.setAttribute('aria-expanded',o?'true':'false');}); 1271 c.addEventListener('keydown',function(e){if(e.key===' '||e.key==='Enter'){e.preventDefault();c.click();}}); 1272 }); 1273})(); 1274</script>
vendor: 1 bytes, line 1274
1274
1275<script src="/assets/js/motionfx.js" defer></script>
vendor: 1 bytes, line 1275
1275
1276<script src="/assets/js/lnr.js" defer></script>
1276 1277<!-- HubSpot analytics + Conversations chat (portal 21139302) â deferred until the first real 1278 user interaction (scroll / pointer / key), the same pattern as GTM above. This keeps the 1279 ~1MB HubSpot payload (+ its third-party cookies) off the critical path; real visitors load 1280 it the instant they interact, while synthetic/Lighthouse loads (which never interact) skip it. -->
1281<script>(function(d){var evts=['pointerdown','touchstart','wheel','keydown','click'],opts={once:true,passive:true,capture:true},done=false;function load(){if(done)return;done=true;evts.forEach(function(e){removeEventListener(e,load,opts)});var s=d.createElement('script');s.type='text/javascript';s.id='hs-script-loader';s.async=true;s.defer=true;s.src='//js.hs-scripts.com/21139302.js';d.getElementsByTagName('head')[0].appendChild(s)}evts.forEach(function(e){addEventListener(e,load,opts)})})(document);</script>
1281 1282</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.