8 in 10 Answered
Order status, parts lookups, and manual questions are handled automatically, so your team can focus on exceptions and escalations.
Your Data Stays Local
Order, parts, and service records stay within your country, so you keep control and can meet local data rules.




import { useEffect, useRef, useState } from "react"
import { addPropertyControls, ControlType } from "framer"
/**
* RE_UseCase1_ListingEnquiries - Customer-support chat with auto-sliding deck.
* Loops forever: plays the full 5.6s thread, pauses briefly, then restarts.
*
* @framerSupportedLayoutWidth any
* @framerSupportedLayoutHeight any
* @framerIntrinsicWidth 518
* @framerIntrinsicHeight 482
*/
export default function RE_UseCase1_ListingEnquiries(props) {
const {
background = false,
restartOnHover = true,
startInView = true,
autoLoop = true,
loopDelay = 1800,
} = props
const ref = useRef<HTMLDivElement>(null)
const [run, setRun] = useState(!startInView)
const [take, setTake] = useState(0)
useEffect(() => {
if (!startInView) return
const el = ref.current
if (!el || typeof IntersectionObserver === "undefined") {
setRun(true)
return
}
const io = new IntersectionObserver(
(es) => {
if (es.some((e) => e.isIntersecting)) {
setRun(true)
io.disconnect()
}
},
{ threshold: 0.35 }
)
io.observe(el)
return () => io.disconnect()
}, [startInView])
const last = useRef(0)
const DURATION = 5600
useEffect(() => {
if (!autoLoop || !run) return
const t = setTimeout(() => {
last.current = Date.now()
setTake((x) => x + 1)
}, DURATION + loopDelay)
return () => clearTimeout(t)
}, [autoLoop, loopDelay, run, take])
const restart = () => {
if (!restartOnHover) return
const now = Date.now()
if (now - last.current < DURATION + 400) return
last.current = now
setRun(true)
setTake((t) => t + 1)
}
const replay = () => {
last.current = Date.now()
setRun(true)
setTake((t) => t + 1)
}
useEffect(() => {
if (run) last.current = Date.now()
}, [run])
return (
<div
ref={ref}
className={"u1" + (background ? " bg" : "")}
onMouseEnter={restart}
onClick={replay}
style={{ cursor: "pointer", ...props.style }}
>
<style>{CSS}</style>
{run && (
<div className="feed" key={take}>
{/* User asks about prerequisites and enrollment */}
<div id="m1" className="row r a">
<div>
<div className="in">
<div className="name">Student</div>
<div className="bub">
I'm trying to enroll in Advanced Data
Structures for next semester. Do I need to
have taken Discrete Math first? And when
does registration open?
<div className="meta">
10:15<span className="tick">✓✓</span>
</div>
</div>
</div>
</div>
</div>
{/* AI typing */}
<div id="d1" className="row l a">
<div>
<div className="in">
<div className="dots">
<i />
<i />
<i />
</div>
</div>
</div>
</div>
{/* AI answers from course catalog */}
<div id="m2" className="row l a">
<div>
<div className="in">
<div className="name">AI agent</div>
<div className="bub">
I checked the course catalog for you.
<br />
<br />
Yes, <strong>Discrete Math (CS 201)</strong>
is a strict prerequisite. You must have
passed it with a C or better.
<br />
<br />
Registration for next semester opens on
<strong> November 1st at 8:00 AM</strong>.
<div className="meta">10:15</div>
</div>
</div>
</div>
</div>
{/* AI typing again */}
<div id="d2" className="row l a">
<div>
<div className="in">
<div className="dots">
<i />
<i />
<i />
</div>
</div>
</div>
</div>
{/* AI provides visual deck of admin docs */}
<div id="m3" className="row l a">
<div>
<div className="in">
<div className="name">AI agent</div>
<div className="bub">
Here are the relevant pages from the
registrar and course catalog:
<div className="deck">
<div id="cM" className="cd">
<img
src="https://images.unsplash.com/photo-1523050854058-8df90110c9f1?w=400&q=80"
alt="Course Catalog"
/>
<div className="lb">
Course Catalog
<span>CS Dept</span>
</div>
<div className="ok">✓</div>
</div>
<div id="cJ" className="cd">
<img
src="https://images.unsplash.com/photo-1506784983877-45594efa4cbe?w=400&q=80"
alt="Registrar Calendar"
/>
<div className="lb">
Registrar Calendar
<span>Fall 2024</span>
</div>
</div>
<div id="cB" className="cd">
<img
src="https://images.unsplash.com/photo-1498243691581-b145c3f54a5a?w=400&q=80"
alt="Prerequisite Guide"
/>
<div className="lb">
Prerequisite Guide
<span>Page 8</span>
</div>
</div>
<div id="tJ" className="tap" />
<div id="tM" className="tap" />
</div>
<div className="pills">
<div id="pc" className="pill a">
View enrollment info
<div
id="tC"
className="tap a"
style={{ right: -8, top: -6 }}
/>
</div>
<div className="pill">Other</div>
</div>
<div className="meta">10:16</div>
</div>
</div>
</div>
</div>
{/* Confirmation card */}
<div id="bk" className="row l a">
<div>
<div className="in">
<div className="book">
<div className="ic">🎓</div>
<div>
<div className="t1">
Prerequisites verified · Ready to
enroll
</div>
<div className="t2">
Registration opens Nov 1 · CS 201
requirement met
</div>
</div>
</div>
</div>
</div>
</div>
</div>
)}
{!run && <div className="feed" />}
<div className="input">
Ask about enrollment...<span>➤</span>
</div>
</div>
)
}
addPropertyControls(RE_UseCase1_ListingEnquiries, {
background: {
type: ControlType.Boolean,
title: "Gradient bg",
defaultValue: false,
},
restartOnHover: {
type: ControlType.Boolean,
title: "Restart on hover",
defaultValue: true,
},
startInView: {
type: ControlType.Boolean,
title: "Start when visible",
defaultValue: true,
},
autoLoop: {
type: ControlType.Boolean,
title: "Auto loop",
defaultValue: true,
},
loopDelay: {
type: ControlType.Number,
title: "Loop pause (ms)",
defaultValue: 1800,
min: 0,
max: 8000,
step: 200,
},
})
const CSS = `
/* Root: fully transparent */
.u1{position:relative;container-type:inline-size;box-sizing:border-box;width:100%;height:100%;min-height:340px;border-radius:22px;overflow:hidden;font-family:'Inter',-apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,sans-serif;color:#1F2430;display:flex;flex-direction:column;padding:clamp(14px,4%,24px) clamp(14px,4.5%,22px);background:transparent}
.u1.bg{background:transparent}
.u1 *{box-sizing:border-box}
.u1 .a{animation-duration:5.6s;animation-iteration-count:1;animation-fill-mode:forwards;animation-timing-function:cubic-bezier(.22,1,.36,1)}
.u1 .feed{flex:1;min-height:0;display:flex;flex-direction:column;justify-content:flex-end;gap:0}
.u1 .row{display:grid;grid-template-rows:0fr;opacity:0}
.u1 .row>div{min-height:0;overflow:hidden}
.u1 .row .in{padding-bottom:14px;display:flex;flex-direction:column;align-items:flex-start}
.u1 .row.r .in{align-items:flex-end}
.u1 .name{font-size:11.5px;color:#8A94A6;margin:0 4px 4px;font-weight:500}
.u1 .bub{max-width:78%;padding:11px 14px;border-radius:14px;font-size:14px;line-height:1.5;box-shadow:0 1px 2px rgba(16,24,40,.06);position:relative;color:#1F2430}
.u1 .r .bub{background:#5B6472;color:#FFFFFF;border-bottom-right-radius:5px}
.u1 .l .bub{background:#FFFFFF;border-bottom-left-radius:5px}
.u1 .meta{display:flex;justify-content:flex-end;gap:4px;font-size:10px;color:#9AA3B2;margin-top:4px}
.u1 .r .meta{color:rgba(255,255,255,.55)}
.u1 .tick{color:rgba(255,255,255,.75);font-weight:700}
.u1 .dots{display:inline-flex;gap:4px;padding:12px 14px;background:#FFFFFF;border-radius:14px;border-bottom-left-radius:5px;box-shadow:0 1px 2px rgba(16,24,40,.06)}
.u1 .dots i{width:6px;height:6px;border-radius:50%;background:#A6AEBD;animation:u1b 1s ease-in-out infinite}
.u1 .dots i:nth-child(2){animation-delay:.15s}.u1 .dots i:nth-child(3){animation-delay:.3s}
@keyframes u1b{0%,100%{opacity:.35;transform:translateY(0)}50%{opacity:1;transform:translateY(-3px)}}
.u1 .who{font-size:11px;font-weight:700;color:#5B6472;margin-bottom:2px}
/* deck - auto sliding carousel */
.u1 .deck{position:relative;height:150px;width:100%;max-width:260px;margin:10px 0 0 0}
.u1 .cd{position:absolute;left:0;top:0;width:172px;height:118px;border-radius:12px;overflow:hidden;box-shadow:0 6px 18px rgba(16,24,40,.18);background:#000;transform-origin:50% 100%}
.u1 .cd img{width:100%;height:100%;object-fit:cover;display:block}
.u1 .cd .lb{position:absolute;left:0;right:0;bottom:0;padding:6px 9px;background:linear-gradient(transparent,rgba(0,0,0,.72));color:#fff;font-size:11.5px;font-weight:700;display:flex;justify-content:space-between}
.u1 .cd .lb span{font-weight:500;opacity:.9}
.u1 .cd .ok{position:absolute;top:8px;right:8px;width:22px;height:22px;border-radius:50%;background:#12A150;color:#fff;font-size:12px;font-weight:800;display:flex;align-items:center;justify-content:center;opacity:0}
/* Auto-slide: 3 cards loop infinitely */
.u1 #cM{animation:u1cM 4.8s ease-in-out infinite;z-index:3}
.u1 #cJ{animation:u1cJ 4.8s ease-in-out infinite;z-index:2}
.u1 #cB{animation:u1cB 4.8s ease-in-out infinite;z-index:1}
@keyframes u1cM{
0%,33.33% {transform:translate(0,0) rotate(0deg);z-index:3}
33.34%,41.66% {transform:translate(18px,9px) rotate(3deg);z-index:2}
41.67%,100% {transform:translate(36px,16px) rotate(6deg);z-index:1}
}
@keyframes u1cJ{
0%,33.33% {transform:translate(18px,9px) rotate(3deg);z-index:2}
33.34%,41.66% {transform:translate(36px,16px) rotate(6deg);z-index:1}
41.67%,100% {transform:translate(0,0) rotate(0deg);z-index:3}
}
@keyframes u1cB{
0%,33.33% {transform:translate(36px,16px) rotate(6deg);z-index:1}
33.34%,41.66% {transform:translate(0,0) rotate(0deg);z-index:3}
41.67%,100% {transform:translate(18px,9px) rotate(3deg);z-index:2}
}
/* ✓ badge visibility */
@keyframes u1okM{0%,33.33%{opacity:1}33.34%,100%{opacity:0}}
@keyframes u1okJ{0%,33.33%{opacity:0}33.34%,66.66%{opacity:1}66.67%,100%{opacity:0}}
@keyframes u1okB{0%,66.66%{opacity:0}66.67%,100%{opacity:1}}
.u1 #cM .ok{animation:u1okM 4.8s steps(1) infinite}
.u1 #cJ .ok{animation:u1okJ 4.8s steps(1) infinite}
.u1 #cB .ok{animation:u1okB 4.8s steps(1) infinite}
/* tap ripples */
.u1 .tap{position:absolute;width:26px;height:26px;border-radius:50%;border:2px solid #fff;background:rgba(255,255,255,.35);opacity:0;pointer-events:none;z-index:9;animation-timing-function:ease-out;animation-iteration-count:infinite}
.u1 #tJ{left:140px;top:62px;animation:u1tJ 4.8s ease-out infinite}
.u1 #tM{left:72px;top:54px;animation:u1tM 4.8s ease-out infinite}
@keyframes u1tJ{0%,33.33%{opacity:0;transform:scale(.4)}35%,38%{opacity:1;transform:scale(.7)}41.66%,100%{opacity:0;transform:scale(1.6)}}
@keyframes u1tM{0%,66.66%{opacity:0;transform:scale(.4)}68.33%,71.33%{opacity:1;transform:scale(.7)}75%,100%{opacity:0;transform:scale(1.6)}}
/* quick replies + booking */
.u1 .pills{display:flex;gap:8px;margin-top:10px}
.u1 .pill{font-size:12.5px;font-weight:600;padding:7px 12px;border-radius:999px;border:1.5px solid #5B6472;color:#5B6472;background:#FFFFFF;position:relative}
/* Primary CTA: outline by default, green fill on click */
.u1 #pc{animation-name:u1pc;animation-timing-function:steps(1)}
@keyframes u1pc{
0%,82.143%{background:transparent;color:#5B6472;border-color:#5B6472}
82.321%,100%{background:#12A150;color:#FFFFFF;border-color:#12A150}
}
.u1 #tC{left:auto;top:auto;animation-name:u1tC;position:absolute}
@keyframes u1tC{0%,80.357%{opacity:0;transform:scale(.4)}82.143%{opacity:1;transform:scale(.7)}88.393%,100%{opacity:0;transform:scale(1.6)}}
.u1 .book{display:flex;gap:10px;align-items:center;background:#FFFFFF;border-radius:14px;padding:11px 14px;box-shadow:0 1px 2px rgba(16,24,40,.06);max-width:88%;color:#1F2430}
.u1 .book .ic{width:36px;height:36px;border-radius:10px;background:rgba(18,161,80,.14);color:#12A150;display:flex;align-items:center;justify-content:center;font-size:18px;flex-shrink:0}
.u1 .book .t1{font-size:13px;font-weight:700}.u1 .book .t2{font-size:12px;color:#6B7280;margin-top:2px}
/* Message entry animations */
@keyframes u1m1{0%,0.000%{grid-template-rows:0fr;opacity:0;transform:translateY(8px)}5.357%,100%{grid-template-rows:1fr;opacity:1;transform:none}}
@keyframes u1m2{0%,8.929%{grid-template-rows:0fr;opacity:0;transform:translateY(8px)}14.286%,100%{grid-template-rows:1fr;opacity:1;transform:none}}
@keyframes u1m3{0%,50.000%{grid-template-rows:0fr;opacity:0;transform:translateY(8px)}55.357%,100%{grid-template-rows:1fr;opacity:1;transform:none}}
@keyframes u1m4{0%,62.500%{grid-template-rows:0fr;opacity:0;transform:translateY(8px)}67.857%,100%{grid-template-rows:1fr;opacity:1;transform:none}}
@keyframes u1bk{0%,89.286%{grid-template-rows:0fr;opacity:0;transform:translateY(8px)}94.643%,100%{grid-template-rows:1fr;opacity:1;transform:none}}
.u1 #m1{animation-name:u1m1}.u1 #m2{animation-name:u1m2}.u1 #m3{animation-name:u1m3}.u1 #m4{animation-name:u1m4}.u1 #bk{animation-name:u1bk}
/* typing rows collapse once the reply lands */
@keyframes u1d1x{0%,3.571%{grid-template-rows:0fr;opacity:0}6.250%,8.036%{grid-template-rows:1fr;opacity:1}10.714%,100%{grid-template-rows:0fr;opacity:0}}
@keyframes u1d2x{0%,55.357%{grid-template-rows:0fr;opacity:0}58.036%,61.607%{grid-template-rows:1fr;opacity:1}64.286%,100%{grid-template-rows:0fr;opacity:0}}
.u1 #d1{animation-name:u1d1x}.u1 #d2{animation-name:u1d2x}
/* Input bar */
.u1 .input{margin-top:8px;height:44px;border-radius:12px;background:#FFFFFF;border:1px solid #E3E6EC;display:flex;align-items:center;padding:0 14px;font-size:13.5px;color:#9AA3B2;flex-shrink:0}
.u1 .input span{margin-left:auto;opacity:.7;color:#5B6472}
/* narrow (phone) */
@container (max-width: 400px) {
.u1 .bub{max-width:92%;font-size:13.5px;padding:10px 12px}
.u1 .pills{flex-wrap:wrap}
.u1 .pill{white-space:nowrap;font-size:12px;padding:6px 11px}
.u1 .call,.u1 .book{max-width:100%}
.u1 .deck{max-width:100%}
.u1 .input{height:42px;font-size:13px}
}
`
What are AI agents for supply chain?
They help with everyday questions about orders, parts, warranties, and service. They can also complete simple tasks or bring in a team member when needed.
Is this AI logistics software or a chatbot?
What is autonomous agentic AI supply chain software?
Will it replace our supply chain team?
How fast can we go live?
Ready to Talk?
Book a short demo and see AutomatiCworX handle your parts, orders, and warranty questions.