PageSourceSearch

https://infi.us/news

html infi.us collected 2026-09-24 10:52:22 UTC 96,297 bytes, 1,282 lines download raw bytes

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&nbsp;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 &amp; 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 &amp; Growth</a>
947          <p class="nav__grp">Operations &amp; 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 &amp; countertop</small></a>
1004  <a href="/products/online-ordering">Online Ordering <small>Web &amp; QR</small></a>
1005  <a href="/products/mobile-app">Branded Mobile App <small>iOS &amp; Android</small></a>
1006  <p class="mnav__grp">Customer Engagement</p>
1007  <a href="/products/loyalty">Loyalty &amp; 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 &amp; SEO</small></a>
1011  <a href="/products/marketing">Online Presence &amp; Growth <small>Google, reviews &amp; SEO</small></a>
1012  <p class="mnav__grp">Operations &amp; 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 &amp; 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 &amp; 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 &amp; <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 &amp; 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 &amp; 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 &amp; 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 &amp; Growth</a><a href="/products/loyalty">Loyalty &amp; 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 &amp; 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.