1import{r as o,j as e}from"./react-vendor-VptLKEvj.js";import{h as d,C as E,P as D,S as I,X as T}from"./index-BWlUU3al.js";import{a as q,P as _}from"./panel-left-open-BmY43LjN.js";import{S as M}from"./search-BC37Q49x.js";import{R as k}from"./refresh-cw-DNgobzAg.js";import{M as P}from"./maximize-2-BHglp0EJ.js";import"./ui-vendor-BsZg97Zl.js";const C=[{key:"standards-nav",label:"Standards & Tokens",dot:"#13C6FF",items:[{id:"standards-duration",label:"Duration scale"},{id:"standards-easing",label:"Easing functions"},{id:"standards-triggers",label:"Trigger conventions"},{id:"standards-tech",label:"Technology guide"},{id:"standards-audit",label:"Inconsistency audit"}]},{key:"micro",label:"Micro-interactions",dot:"#4b57a5",items:[{id:"micro-hover",label:"Hover states"},{id:"micro-focus",label:"Focus states"},{id:"micro-active",label:"Active / press"},{id:"micro-toggle",label:"Toggle states"}]},{key:"entrance",label:"Entrance & Exit",dot:"#0EA5E9",items:[{id:"entrance-fade",label:"Fade reveal"},{id:"entrance-slide",label:"Slide in / out"},{id:"entrance-scale",label:"Scale in / out"},{id:"entrance-stagger",label:"Stagger sequences"}]},{key:"scroll",label:"Scroll-driven",dot:"#5CB047",items:[{id:"scroll-reveal-section",label:"Viewport reveal"},{id:"scroll-stagger",label:"Stagger cascade"},{id:"scroll-mask",label:"Mask / gradient fade"},{id:"scroll-progress",label:"Scroll progress"}]},{key:"nav-trans",label:"Navigation & Transitions",dot:"#B775D6",items:[{id:"nav-tabs",label:"Tab switching"},{id:"nav-drawer",label:"Menu / drawer"},{id:"nav-overlay",label:"Overlay entry"},{id:"nav-route",label:"Route transitions"}]},{key:"ambient",label:"Continuous / Ambient",dot:"#13C6FF",items:[{id:"ambient-loop",label:"Looping keyframes"},{id:"ambient-pulse",label:"Pulse / heartbeat"},{id:"ambient-marquee",label:"Marquee / ticker"},{id:"ambient-float",label:"Float / bob"}]},{key:"seq",label:"Orchestrated Sequences",dot:"#E76F51",items:[{id:"seq-hero",label:"Hero entrance"},{id:"seq-svg",label:"SVG scenes"},{id:"seq-multi",label:"Multi-step reveals"}]},{key:"data",label:"Data Visualization",dot:"#13C6FF",items:[{id:"data-graph",label:"Graph / network"},{id:"data-canvas",label:"Canvas / rAF loops"},{id:"data-scroll",label:"Scroll-driven data"}]},{key:"sys",label:"System / Overlay",dot:"#556480",items:[{id:"sys-modal",label:"Modal / dialog"},{id:"sys-accordion",label:"Accordion"},{id:"sys-toast",label:"Toast / notification"},{id:"sys-tooltip",label:"Tooltip"}]}],j="radial-gradient(ellipse 180% 350% at -5% 100%, rgba(183,117,214,0.38) 0%, rgba(206,241,255,0.15) 42%, rgba(231,164,159,0.13) 71%, rgba(255,87,64,0.11) 100%), rgba(253,253,253,0.72)",N="0px 0px 8px 0px rgba(19,198,255,0.24)",B=({isOpen:t,onOpenChange:s})=>{const[a,i]=o.useState(""),[n,c]=o.useState(new Set),m=o.useRef(null),p=o.useRef(null);o.useEffect(()=>{if(!t)return;const l=u=>{u.key==="Escape"&&s(!1)};return document.addEventListener("keydown",l),()=>document.removeEventListener("keydown",l)},[t,s]),o.useEffect(()=>{var l,u;if(t){const x=setTimeout(()=>{var S;return(S=m.current)==null?void 0:S.focus()},50);return()=>clearTimeout(x)}else(l=document.activeElement)!=null&&l.closest("#brand-animation-nav")&&((u=p.current)==null||u.focus())},[t]);const g=a.trim().length>0,v=o.useMemo(()=>{const l=a.trim().toLowerCase();return l?C.map(u=>({...u,items:u.items.filter(x=>x.label.toLowerCase().includes(l))})).filter(u=>u.items.length>0):C},[a]),b=l=>g?!0:!n.has(l),F=l=>{c(u=>{const x=new Set(u);return x.has(l)?x.delete(l):x.add(l),x})};return e.jsxs(e.Fragment,{children:[e.jsxs("div",{className:d("group fixed top-[82px] left-4 z-40 flex items-center",t?"hidden":"hidden lg:flex"),children:[e.jsx("span",{id:"brand-anim-fab-tooltip",role:"tooltip","aria-hidden":"true",className:"pointer-events-none absolute left-0 top-1/2 -translate-y-1/2 whitespace-nowrap rounded-full py-[9px] pl-[56px] pr-[18px] font-operator font-[700] text-[11px] uppercase tracking-[1.6px] text-[#202152] backdrop-blur-[12px] opacity-0 -translate-x-2 transition-all duration-300 ease-out group-hover:opacity-100 group-hover:translate-x-0 group-focus-within:opacity-100 group-focus-within:translate-x-0",style:{background:j,boxShadow:N},children:"Animation Catalog"}),e.jsx("button",{ref:p,type:"button",onClick:()=>s(!0),"aria-expanded":t,"aria-controls":"brand-animation-nav","aria-label":"Open Animation Catalog","aria-describedby":"brand-anim-fab-tooltip",className:"relative z-10 flex h-11 w-11 items-center justify-center rounded-full backdrop-blur-[12px] text-[#091133] transition-all duration-200 hover:scale-105 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-[#13c6ff] focus-visible:ring-offset-2",style:{background:j,boxShadow:N},children:e.jsx(q,{className:"h-5 w-5"})})]}),e.jsxs("aside",{id:"brand-animation-nav","aria-label":"Animation catalog navigation",className:d("fixed left-0 top-0 bottom-0 z-40 hidden w-80 flex-col backdrop-blur-[12px] border-r border-[rgba(19,198,255,0.24)]","transform transition-transform duration-300 ease-out","lg:flex",t?"translate-x-0":"-translate-x-full"),style:{background:j,boxShadow:N},children:[e.jsx("div",{className:"h-[66px] shrink-0"}),e.jsxs("div",{className:"shrink-0 px-4 pb-4 pt-4",children:[e.jsxs("div",{className:"mb-3 flex items-center justify-between",children:[e.jsx("p",{className:"font-operator font-[700] text-[11px] uppercase tracking-[1.6px] text-[#202152]",children:"Animation Catalog"}),e.jsx("button",{type:"button",onClick:()=>s(!1),"aria-label":"Close animation navigation",title:"Close (Esc)",className:"flex h-7 w-7 items-center justify-center rounded-full text-[#091133] transition-colors hover:bg-[rgba(19,198,255,0.15)] focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-[#13c6ff]",children:e.jsx(_,{className:"h-4 w-4"})})]}),e.jsxs("div",{className:"relative",children:[e.jsx(M,{className:"pointer-events-none absolute left-3 top-1/2 h-4 w-4 -translate-y-1/2 text-[#6b7280]"}),e.jsx("input",{ref:m,type:"text",value:a,onChange:l=>i(l.target.value),placeholder:"Filter animations",className:"w-full appearance-none rounded-[8px] border-2 border-solid border-[rgba(19,198,255,0.66)] bg-[rgba(207,243,255,0.66)] py-[6px] pl-9 pr-[8px] font-operator font-[325] text-[14px] leading-[20px] text-[#282966] transition-all duration-150 placeholder:text-[#6b7280] focus:border-[#13c6ff] focus:shadow-[0px_0px_8px_0px_#13c6ff] focus:outline-none"})]})]}),e.jsx("nav",{className:"flex-1 overflow-y-auto px-2 pb-8",children:v.length===0?e.jsxs("p",{className:"px-4 font-gotham-narrow text-[13px] text-[#202152]",children:['No entries match "',a,'"']}):v.map(l=>{const u=b(l.key);return e.jsxs("div",{className:"mb-2",children:[e.jsxs("button",{type:"button",onClick:()=>F(l.key),"aria-expanded":u,"aria-controls":`cat-${l.key}`,className:"flex w-full items-center justify-between rounded-[6px] px-3 py-2 font-gotham font-[900] text-[12px] uppercase tracking-[0.24px] text-[#091133] hover:bg-[rgba(19,198,255,0.1)] focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-[#13c6ff]",children:[e.jsxs("span",{className:"flex items-center gap-2",children:[e.jsx("span",{className:"h-2 w-2 rounded-full shrink-0",style:{background:l.dot}}),l.label,e.jsx("span",{className:"font-operator font-[400] text-[10px] text-[#4b57a5]",children:l.items.length})]}),e.jsx(E,{className:d("h-4 w-4 transition-transform duration-200",!u&&"-rotate-90")})]}),u&&e.jsx("ul",{id:`cat-${l.key}`,className:"mt-1 space-y-0.5 pl-5",children:l.items.map(x=>e.jsx("li",{children:e.jsx("a",{href:`#${x.id}`,className:"block rounded-[4px] px-3 py-1.5 font-gotham-narrow text-[13px] leading-[18px] text-[#202152] transition-colors hover:bg-[rgba(19,198,255,0.12)] hover:text-[#091133] focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-[#13c6ff]",children:x.label})},x.id))})]},l.key)})})]})]})},h=({id:t,title:s,intro:a,children:i})=>e.jsxs("div",{id:t,className:"mb-20 scroll-mt-24",children:[e.jsx("h2",{className:"mb-2 font-gotham font-[900] text-[30px] leading-[36px] tracking-[0.6px] text-[#091133]",children:s}),a&&e.jsx("p",{className:"mb-8 max-w-[760px] font-gotham-narrow text-[14px] leading-[22px] text-[#202152]",children:a}),i]}),f=({id:t,title:s,children:a})=>e.jsxs("div",{id:t,className:"mb-12 scroll-mt-24",children:[e.jsx("h3",{className:"mb-6 font-gotham font-[800] text-[18px] leading-[24px] tracking-[0.36px] text-[#091133]",children:s}),a]}),R={active:{label:"Active",bg:"bg-[rgba(92,176,71,0.12)]",ring:"ring-1 ring-[rgba(92,176,71,0.5)]",text:"text-[#2e6621]"},inconsistent:{label:"Inconsistent",bg:"bg-[rgba(255,164,0,0.12)]",ring:"ring-1 ring-[rgba(255,164,0,0.5)]",text:"text-[#7a4d00]"},missing:{label:"Missing",bg:"bg-[rgba(255,87,64,0.10)]",ring:"ring-1 ring-[rgba(255,87,64,0.4)]",text:"text-[#9b3a23]"},recommended:{label:"Recommended",bg:"bg-[rgba(19,198,255,0.12)]",ring:"ring-1 ring-[rgba(19,198,255,0.4)]",text:"text-[#0a7da3]"}},G=({status:t})=>{const s=R[t];return e.jsx("span",{className:d("inline-flex items-center rounded-full px-2 py-[2px] font-operator font-[700] text-[10px] uppercase tracking-[1.2px]",s.bg,s.ring,s.text),children:s.label})},O={"tailwind-keyframe":"Tailwind keyframe","css-transition":"CSS transition","css-keyframe":"CSS @keyframe","js-state":"JS/React state","intersection-observer":"IntersectionObserver","scroll-event":"scroll event",requestAnimationFrame:"rAF loop","svg-inline":"inline SVG","tailwindcss-animate":"tailwindcss-animate"},H=({tech:t})=>e.jsx("span",{className:"inline-flex items-center rounded-full bg-[rgba(207,243,255,0.5)] px-2 py-[1px] font-operator text-[10px] leading-[16
1px] text-[#202152]",children:O[t]}),V=({children:t,minHeight:s=120})=>{const[a,i]=o.useState(0),[n,c]=o.useState(!1);return o.useEffect(()=>{if(!n)return;const m=p=>{p.key==="Escape"&&c(!1)};return document.addEventListener("keydown",m),()=>document.removeEventListener("keydown",m)},[n]),e.jsxs(e.Fragment,{children:[e.jsxs("div",{className:"group relative overflow-hidden rounded-[8px] border border-dashed border-[rgba(19,198,255,0.35)] bg-[rgba(207,243,255,0.18)]",style:{minHeight:s},children:[e.jsx("div",{className:"flex h-full w-full items-center justify-center p-6",children:t},a),e.jsxs("div",{className:"absolute right-2 top-2 flex gap-1 opacity-0 transition-opacity group-hover:opacity-100",children:[e.jsx("button",{type:"button",onClick:()=>i(m=>m+1),"aria-label":"Replay animation",title:"Replay",className:"flex h-6 w-6 items-center justify-center rounded-full bg-[rgba(9,17,51,0.06)] text-[#4b57a5] hover:bg-[rgba(19,198,255,0.2)] hover:text-[#091133] transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-[#13c6ff]",children:e.jsx(k,{className:"h-3 w-3"})}),e.jsx("button",{type:"button",onClick:()=>c(!0),"aria-label":"Expand preview",title:"Expand",className:"flex h-6 w-6 items-center justify-center rounded-full bg-[rgba(9,17,51,0.06)] text-[#4b57a5] hover:bg-[rgba(19,198,255,0.2)] hover:text-[#091133] transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-[#13c6ff]",children:e.jsx(P,{className:"h-3 w-3"})})]})]}),n&&e.jsx("div",{role:"dialog","aria-modal":"true","aria-label":"Animation preview expanded",className:"fixed inset-0 z-50 flex items-center justify-center bg-[rgba(9,17,51,0.72)] backdrop-blur-sm",onClick:()=>c(!1),children:e.jsxs("div",{className:"relative w-full max-w-2xl rounded-[20px] border border-[rgba(19,198,255,0.3)] bg-[rgba(253,253,253,0.96)] p-12 shadow-[0_24px_80px_rgba(9,17,51,0.24)]",onClick:m=>m.stopPropagation(),children:[e.jsx("button",{type:"button",onClick:()=>c(!1),"aria-label":"Close expanded preview",className:"absolute right-4 top-4 flex h-8 w-8 items-center justify-center rounded-full text-[#4b57a5] hover:bg-[rgba(19,198,255,0.15)] transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-[#13c6ff]",children:e.jsx(T,{className:"h-4 w-4"})}),e.jsx("div",{className:"flex min-h-[200px] items-center justify-center",children:t},a),e.jsx("div",{className:"mt-6 flex justify-center",children:e.jsxs("button",{type:"button",onClick:()=>i(m=>m+1),className:"inline-flex items-center gap-2 rounded-full border border-[rgba(19,198,255,0.5)] bg-[rgba(207,243,255,0.5)] px-4 py-1.5 font-operator font-[700] text-[10px] uppercase tracking-[1.4px] text-[#091133] hover:bg-[rgba(19,198,255,0.2)] transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-[#13c6ff]",children:[e.jsx(k,{className:"h-3 w-3"})," Replay"]})})]})})]})},r=({id:t,name:s,status:a,tech:i,duration:n,easing:c,description:m,note:p,files:g,children:v})=>e.jsxs("div",{id:t,className:"scroll-mt-24 rounded-[12px] border border-[rgba(19,198,255,0.28)] bg-white/60 p-5 backdrop-blur-sm",children:[e.jsxs("div",{className:"mb-3 flex flex-wrap items-start gap-2",children:[e.jsx("h4",{className:"mr-auto font-gotham font-[800] text-[14px] leading-[18px] text-[#091133]",children:s}),e.jsx(G,{status:a})]}),e.jsxs("div",{className:"mb-3 flex flex-wrap gap-1.5",children:[i.map(b=>e.jsx(H,{tech:b},b)),e.jsx("span",{className:"inline-flex items-center rounded-full bg-[rgba(75,87,165,0.08)] px-2 py-[1px] font-operator text-[10px] leading-[16px] text-[#4b57a5]",children:n}),e.jsx("span",{className:"inline-flex items-center rounded-full bg-[rgba(75,87,165,0.08)] px-2 py-[1px] font-operator text-[10px] leading-[16px] text-[#4b57a5]",children:c})]}),e.jsx(V,{children:v}),e.jsx("p",{className:"mt-3 font-gotham-narrow text-[13px] leading-[18px] text-[#202152]",children:m}),p&&e.jsxs("p",{className:"mt-2 rounded-[6px] bg-[rgba(255,164,0,0.08)] border border-[rgba(255,164,0,0.3)] px-3 py-2 font-gotham-narrow text-[12px] leading-[17px] text-[#7a4d00]",children:[e.jsx("span",{className:"font-operator font-[700] uppercase tracking-[1.2px] text-[10px]",children:"Note · "}),p]}),g.length>0&&e.jsx("div",{className:"mt-3 flex flex-wrap gap-1.5",children:g.map(b=>e.jsx("code",{className:"rounded-[4px] bg-[rgba(207,243,255,0.4)] px-2 py-[2px] font-operator text-[10px] leading-[14px] text-[#202152]",children:b},b))})]}),w=({head:t,rows:s})=>e.jsx("div",{className:"overflow-x-auto scrollbar-hide rounded-[10px] border border-[rgba(19,198,255,0.3)] text-[13px] mb-8",children:e.jsxs("table",{className:"w-full",children:[e.jsx("thead",{children:e.jsx("tr",{className:"bg-[rgba(207,243,255,0.4)]",children:t.map(a=>e.jsx("th",{className:"px-4 py-2.5 text-left font-gotham-narrow font-[700] text-[#091133]",children:a},a))})}),e.jsx("tbody",{children:s.map((a,i)=>e.jsx("tr",{className:i%2===1?"bg-[rgba(207,243,255,0.12)]":"",children:a.map((n,c)=>e.jsx("td",{className:"px-4 py-2.5 font-gotham-narrow text-[13px] text-[#202152]",children:n},c))},i))})]})}),y=({severity:t,issue:s,detail:a,fix:i})=>{const n={high:{dot:"bg-[#ff5740]",label:"text-[#9b3a23]",bg:"bg-[rgba(255,87,64,0.06)]"},medium:{dot:"bg-[#ffa400]",label:"text-[#7a4d00]",bg:"bg-[rgba(255,164,0,0.06)]"},low:{dot:"bg-[#13c6ff]",label:"text-[#0a7da3]",bg:"bg-[rgba(19,198,255,0.06)]"}}[t];return e.jsxs("div",{className:d("rounded-[10px] border border-[rgba(19,198,255,0.2)] p-4 mb-3",n.bg),children:[e.jsxs("div",{className:"mb-1 flex items-center gap-2",children:[e.jsx("span",{className:d("h-2 w-2 rounded-full shrink-0",n.dot)}),e.jsx("span",{className:d("font-gotham font-[800] text-[13px]",n.label),children:s})]}),e.jsx("p",{className:"mb-1 font-gotham-narrow text-[12px] leading-[17px] text-[#202152]",children:a}),e.jsxs("p",{className:"font-gotham-narrow text-[12px] leading-[17px] text-[#4b57a5]",children:[e.jsx("span",{className:"font-operator font-[700] text-[10px] uppercase tracking-[1.2px] text-[#202152]",children:"Fix â "}),i]})]})},z=()=>{const[t,s]=o.useState(!1),a=o.useRef(null);return o.useEffect(()=>{const i=a.current;if(!i)return;const n=new IntersectionObserver(([c])=>{c.isIntersecting&&s(!0)},{threshold:.4});return n.observe(i),()=>n.disconnect()},[]),e.jsx("div",{ref:a,children:e.jsx("div",{className:"transition-all duration-500 ease-out",style:{opacity:t?1:0,transform:t?"translateY(0)":"translateY(20px)"},children:e.jsx("span",{className:"font-gotham font-[800] text-[18px] text-[#091133]",children:"Content revealed on scroll"})})})},le=()=>{const[t,s]=o.useState(()=>typeof window>"u"?!1:localStorage.getItem("brand-animation-nav-open")==="1");return o.useEffect(()=>{localStorage.setItem("brand-animation-nav-open",t?"1":"0")},[t]),e.jsxs(D,{children:[e.jsx(I,{title:"Brand Animation Catalog",description:"Fluree animation system â taxonomy, live demos, standards, and inconsistency audit.",noindex:!0}),e.jsx(B,{isOpen:t,onOpenChange:s}),e.jsx("div",{className:d("transition-[margin-left] duration-300 ease-out",t?"lg:ml-80":"ml-0"),children:e.jsx("section",{className:"pb-20 pt-32 md:pt-40",children:e.jsxs("div",{className:d("container px-6",t?"lg:mx-0 lg:max-w-none mx-auto":"mx-auto"),children:[e.jsx("div",{className:"mb-4 inline-flex items-center rounded-[1px] bg-[#13c6ff] px-[14px] py-[4px]",children:e.jsx("span",{className:"font-gotham font-[400] text-[11px] leading-[15px] tracking-[0.55px] text-[#091133]",children:"INTERNAL · NOT INDEXED"})}),e.jsx("h1",{className:"font-gotham font-[800] text-[48px] leading-[50px] tracking-[0.96px] text-[#091133] md:text-[60px] md:leading-[62px]",children:"Brand Animation Catalog"}),e.jsx("p",{className:"mt-4 max-w-[780px] font-gotham-narrow text-[18px] leading-[28px] text-[#202152]",children:"Every motion on the Fluree site â documented, demoed, and audited. Covers current state, recommended standards, and inconsistencies to resolve. No external animation libraries are used; all motion is declarative CSS, Tailwind keyframes, or SVG."}),e.jsx("div",{className:"mt-6 flex flex-wrap items-center gap-4 font-operator text-[12px] uppercase tracking-[1.4px] text-[#202152]",children:["active","inconsistent","missing","recommended"].map(a=>{const i=R[a];return e.jsx("span",{className:d("rounded-[1px] px-2 py-[2px]",i.bg,i.text),children:i.label},a)})}),e.jsx("div",{className:"mt-16"}),e.jsxs(h,{id:"standards-duration",title:"Standards & Tokens",intro:"The rules every Fluree animation must follow. Duration scale, easing tokens, trigger conventions, te
1chnology guide, and the current inconsistency audit.",children:[e.jsxs(f,{id:"standards-duration",title:"Duration Scale",children:[e.jsx(w,{head:["Name","Range","Token / class","Use when"],rows:[["Instant","0 ms","â","State with no transition needed (visibility toggle with no motion)"],["Snap","100 ms","duration-100","Button press confirm, checkbox tick, icon swap"],["Fast","150 ms","duration-150","Hover state enter/exit, focus ring appear, tooltip show"],["Normal","200â300 ms","duration-200 / 300","Tab switch, accordion open, dropdown reveal, panel slide"],["Slow","400â600 ms","duration-500","Section entrance (ScrollReveal), hero reveal, page-level transitions"],["Ambient","2 000â4 000 ms","duration-[2000ms]+","Marquee ticker, float/bob loop, pulse heartbeat, SVG path draw"]]}),e.jsxs("p",{className:"mt-2 font-gotham-narrow text-[13px] text-[#4b57a5]",children:["Duration standard is 8à the base grid where possible (8, 16, 24, ⦠ms). Tailwind's default scale covers 75â1000 ms. Ambient animations use arbitrary values: ",e.jsx("code",{className:"font-operator text-[11px]",children:"duration-[2400ms]"})," etc."]})]}),e.jsxs(f,{id:"standards-easing",title:"Easing Functions",children:[e.jsx(w,{head:["Name","Value","Use when"],rows:[["ease-out","cubic-bezier(0, 0, 0.58, 1)","Entrance animations â elements enter fast, settle gently"],["ease-in-out","cubic-bezier(0.42, 0, 0.58, 1)","Ambient loops (float, pulse), hover lift, panel toggles"],["linear","cubic-bezier(0, 0, 1, 1)","Marquee ticker, scroll progress bar, constant-speed motion"],["spring","cubic-bezier(0.16, 1, 0.3, 1)","RECOMMENDED for panel slide-in, nav drawer, modal entry (not yet in use)"]]}),e.jsxs("p",{className:"mt-2 font-gotham-narrow text-[13px] text-[#4b57a5]",children:["Tailwind utility classes: ",e.jsx("code",{className:"font-operator text-[11px]",children:"ease-out"}),", ",e.jsx("code",{className:"font-operator text-[11px]",children:"ease-in-out"}),", ",e.jsx("code",{className:"font-operator text-[11px]",children:"ease-linear"}),". The spring curve requires an arbitrary value: ",e.jsx("code",{className:"font-operator text-[11px]",children:"[cubic-bezier(0.16,1,0.3,1)]"}),"."]})]}),e.jsx(f,{id:"standards-triggers",title:"Trigger Conventions",children:e.jsx(w,{head:["Trigger","Pattern","Notes"],rows:[["Page load","CSS animation on mount (animate-fade-up)","Hero only. No other content animates on hard load."],["Scroll into view","IntersectionObserver â class/state toggle","ScrollReveal component. threshold: 0.15. Once-only."],["User hover","Tailwind hover: utilities (transition-all duration-*)","No JS required. Always pair enter + exit duration."],["User focus","focus-visible: ring + any state change","Accessibility-first. Must be keyboard-reachable."],["User click/tap","React state â CSS transition","Tab switch, accordion open, panel show/hide."],["Continuous","animation: ⦠infinite","Marquee, pulse, float. Must respect prefers-reduced-motion."],["Scroll progress","scroll event â CSS custom property / inline style","Reading progress bar. Use passive listener."]]})}),e.jsxs(f,{id:"standards-tech",title:"Technology Guide",children:[e.jsx(w,{head:["Technology","When to use","When NOT to use"],rows:[["CSS transition (hover:, focus:)","Interactive state changes: hover lift, focus ring, color swap","Entrance reveals â use keyframes instead"],["Tailwind keyframe (animate-*)","Scroll reveals, hero entrance, ambient loops defined in tailwind.config","One-off durations or non-standard easings"],["CSS @keyframes (index.css)","Complex multi-step paths: marquee, SVG stroke draw, pulse-flow","Simple AâB transitions"],["JS/React state + CSS","Tab switch, accordion, panel toggle, any user-triggered show/hide","Scroll-driven (use IO instead)"],["IntersectionObserver","Viewport entrance reveal, once-only triggers","Continuous or user-triggered animations"],["requestAnimationFrame (rAF)","Canvas animations, FlureeGraphStory particle system","Anything achievable in CSS"],["Inline SVG animation","Orchestrated path draws, knowledge graph scenes","Simple icon states â use CSS transitions"],["tailwindcss-animate (Radix)","Modal/dialog/sheet overlay enter/exit from Radix primitives only","Custom brand animations"]]}),e.jsxs("div",{className:"rounded-[10px] border border-[rgba(255,87,64,0.3)] bg-[rgba(255,87,64,0.06)] px-4 py-3 font-gotham-narrow text-[13px] leading-[18px] text-[#9b3a23]",children:[e.jsx("strong",{children:"Strictly forbidden:"})," Framer Motion, GSAP, anime.js, Lottie, or any external animation runtime. All motion must be achievable with the technologies listed above."]})]}),e.jsxs(f,{id:"standards-audit",title:"Inconsistency Audit",children:[e.jsx("p",{className:"mb-6 font-gotham-narrow text-[13px] text-[#202152]",children:"Known inconsistencies found during the initial audit pass. Address these before introducing new animations."}),e.jsx(y,{severity:"high",issue:"Duplicate marquee keyframes",detail
1:"animate-marquee is defined in both index.css (@keyframes marquee, 40s) and tailwind.config.ts (ticker keyframe, same transform). CustomerStoriesRail and the ticker in tailwind.config each use different names for the same motion.",fix:"Consolidate to a single tailwind.config keyframe named 'marquee'. Remove the @keyframes marquee block from index.css. Standardize on animate-marquee everywhere."}),e.jsx(y,{severity:"high",issue:"Asymmetric tab crossfade durations",detail:"EvaluateShipDefend tab content fades out at duration-150 but fades in at duration-300. This asymmetry is not intentional â it creates a 'snappy hide, slow reveal' feel that looks inconsistent.",fix:"Standardize both phases to duration-200. Or make exit faster (100ms) and entrance Normal (300ms) intentionally and document it."}),e.jsx(y,{severity:"medium",issue:"No documented easing token standard",detail:"Components use ease-out, ease-in-out, and linear without a shared decision document. Some hover states use the default Tailwind ease (ease) instead of ease-out, producing subtly different feels.",fix:"Apply the easing table above. Audit all transition-* classes for implicit ease and replace with ease-out for entrances, ease-in-out for ambient."}),e.jsx(y,{severity:"medium",issue:"ScrollReveal threshold inconsistency",detail:"ScrollReveal uses threshold: 0.15 by default, but several manual IntersectionObserver instances in HowItWorksStage and FlureeGraphStory use threshold: 0.1 or threshold: 0.3.",fix:"Standardize all IntersectionObserver entrance thresholds to 0.15. Extract the ScrollReveal hook for reuse."}),e.jsx(y,{severity:"low",issue:"No prefers-reduced-motion guard on marquee",detail:"CustomerStoriesRail animate-marquee has no @media (prefers-reduced-motion: reduce) guard. The pulse-flow SVG animation is guarded in index.css but marquee is not.",fix:"Add animation: none guard for animate-marquee and animate-ticker in index.css alongside the existing pulse-flow guard."}),e.jsx(y,{severity:"low",issue:"Spring easing missing from the stack",detail:"Panel slide-ins (BrandAnimationNavPanel, DevComponentsNavPanel, Navbar mobile sheet) use ease-out. A spring curve (cubic-bezier(0.16, 1, 0.3, 1)) would feel more physical and premium.",fix:"Add a 'spring' animation preset to tailwind.config and apply to all panel/drawer entrance transitions."})]})]}),e.jsxs(h,{id:"micro-hover",title:"Micro-interactions",intro:"Small, immediate responses to user input. Should feel instant (100â150 ms) and purposeful â every interaction must signal affordance, feedback, or state change.",children:[e.jsx(f,{id:"micro-hover",title:"Hover States",children:e.jsxs("div",{className:"grid gap-4 md:grid-cols-2 xl:grid-cols-3",children:[e.jsx(r,{id:"micro-button-lift",name:"Button lift",status:"active",tech:["css-transition"],duration:"150 ms",easing:"ease-out",description:"FlureeButton primary and outline variants lift on hover via drop-shadow. Communicates clickability and elevation.",files:["src/components/sections/FlureeButton.tsx"],children:e.jsx("div",{className:"inline-flex h-[48px] cursor-pointer items-center justify-center rounded-[32px] bg-[#13c6ff] px-[22px] font-gotham font-[800] text-[16px] text-[#091133] transition-all duration-150 hover:shadow-[0px_4px_4px_0px_rgba(9,19,49,0.24)] hover:-translate-y-px",children:"Hover me"})}),e.jsx(r,{id:"micro-border-glow",name:"Border glow on focus",status:"active",tech:["css-transition"],duration:"150 ms",easing:"ease-out",description:"Input fields and cards reveal a cyan border glow on focus to communicate active state. Consistent with the accent color system.",files:["src/components/sections/FlureeInput.tsx"],children:e.jsx("input",{type:"text",readOnly:!0,defaultValue:"Focus me",className:"w-full max-w-[240px] appearance-none rounded-[8px] border-2 border-[rgba(19,198,255,0.66)] bg-[rgba(207,243,255,0.66)] px-3 py-2 font-operator text-[14px] text-[#282966] transition-all duration-150 focus:border-[#13c6ff] focus:shadow-[0px_0px_8px_0px_#13c6ff] focus:outline-none"})}),e.jsx(r,{id:"micro-card-lift",name:"Card hover lift",status:"active",tech:["css-transition"],duration:"200â300 ms",easing:"ease-out",description:"Feature cards translate -1 to -2px and reveal a subtle shadow on hover, reinfor
1cing their interactivity.",files:["src/components/shared/AIReadinessAssessment.tsx","src/components/shared/WhyFluree.tsx"],children:e.jsxs("div",{className:"w-full max-w-[200px] cursor-pointer rounded-[16px] border border-[rgba(19,198,255,0.2)] bg-white/70 p-4 transition-all duration-300 hover:-translate-y-0.5 hover:border-[rgba(19,198,255,0.4)] hover:shadow-[0_4px_20px_rgba(9,17,51,0.06)]",children:[e.jsx("p",{className:"font-gotham font-[800] text-[13px] text-[#091133]",children:"Hover the card"}),e.jsx("p",{className:"mt-1 font-gotham-narrow text-[11px] text-[#4b57a5]",children:"Subtle lift + shadow"})]})}),e.jsx(r,{id:"micro-link-arrow",name:"Link arrow slide",status:"active",tech:["css-transition"],duration:"200 ms",easing:"ease-out",description:"Inline link arrows translate 4px right on hover via the .link-arrow utility class. Provides directional intent without distracting movement.",files:["src/index.css"],children:e.jsxs("a",{className:"link-arrow group inline-flex cursor-pointer items-center gap-1.5 font-gotham-narrow text-[14px] text-[#091133] underline",children:["Read more",e.jsx("svg",{className:"arrow h-4 w-4 transition-transform duration-200 group-hover:translate-x-1",viewBox:"0 0 16 16",fill:"none",children:e.jsx("path",{d:"M3 8h10M9 4l4 4-4 4",stroke:"currentColor",strokeWidth:"1.5",strokeLinecap:"round",strokeLinejoin:"round"})})]})})]})}),e.jsx(f,{id:"micro-focus",title:"Focus States",children:e.jsx("div",{className:"grid gap-4 md:grid-cols-2 xl:grid-cols-3",children:e.jsx(r,{id:"micro-focus-ring",name:"Cyan focus ring",status:"active",tech:["css-transition"],duration:"150 ms",easing:"ease-out",description:"All interactive elements use a 2px cyan focus ring (focus-visible:ring-2 ring-[#13c6ff] ring-offset-2). Keyboard-only â does not appear on mouse click.",files:["src/components/sections/FlureeButton.tsx","src/index.css"],children:e.jsx("button",{className:"rounded-[32px] bg-[#13c6ff] px-6 py-3 font-gotham font-[800] text-[14px] text-[#091133] focus:outline-none focus-visible:ring-2 focus-visible:ring-[#13c6ff] focus-visible:ring-offset-2",children:"Tab to focus me"})})})}),e.jsx(f,{id:"micro-active",title:"Active / Press",children:e.jsx("div",{className:"grid gap-4 md:grid-cols-2 xl:grid-cols-3",children:e.jsx(r,{id:"micro-button-press",name:"Button inset press",status:"active",tech:["css-transition"],duration:"150 ms",easing:"ease-out",description:"FlureeButton active state adds an inset box-shadow simulating physical depression. Border lightens simultaneously. Both signals fire on mousedown.",files:["src/components/sections/FlureeButton.tsx"],children:e.jsx("div",{className:"inline-flex h-[48px] cursor-pointer select-none items-center justify-center rounded-[32px] border-[1.25px] border-solid border-[#13c6ff] bg-[#13c6ff] px-[22px] font-gotham font-[800] text-[16px] text-[#091133] transition-all duration-150 active:border-[#c9d3ec] active:shadow-none active:shadow-[inset_0px_4px_4px_0px_#00a0d1]",children:"Press + hold"})})})}),e.jsx(f,{id:"micro-toggle",title:"Toggle States",children:e.jsxs("div",{className:"grid gap-4 md:grid-cols-2 xl:grid-cols-3",children:[e.jsx(r,{id:"micro-chevron-rotate",name:"Chevron rotate",status:"active",tech:["css-transition","js-state"],duration:"200 ms",easing:"ease-out",description:"Accordion and collapsible sections rotate ChevronDown 90° when collapsed. The rotate is on the icon element, not the container, avoiding layout shifts.",files:["src/components/shared/BrandAnimationNavPanel.tsx","src/components/shared/BrandImageryNavPanel.tsx"],children:e.jsx(L,{})}),e.jsx(r,{id:"micro-tab-indicator",name:"Tab active indicator",status:"inconsistent",tech:["css-transition","js-state"],duration:"150â300 ms",easing:"ease-out",note:"Fade-in uses duration-300, fade-out uses duration-150. Standardize both to duration-200.",description:"EvaluateShipDefend and HowItWorksStage use opacity + transform crossfade to reveal active tab content. Exit is faster than entrance.",files:["src/components/shared/EvaluateShipDefend.tsx","src/components/shared/HowItWorksStage.tsx"],children:e.jsx(A,{})})]})})]}),e.jsx(h,{id:"entrance-fade",title:"Entrance & Exit",intro:"How elements enter and leave the viewport. Fluree uses fade-and-rise as the canonical reveal pattern. Exits are rarely animated â most content is hidden immediately.",children:e.jsxs("div",{className:"grid gap-4 md:grid-cols-2 xl:grid-cols-3",children:[e.jsx(r,{id:"entrance-fade-reveal",name:"Fade-and-rise reveal",status:"active",tech:["tailwind-keyframe","intersection-observer"],duration:"500 ms",easing:"ease-out",description:"The canonical Fluree reveal pattern. Elements fade from opacity 0 and translateY(20px) to full visibility. Triggered by IntersectionObserver at 15% viewport intersection. Fires once.",files:["src/components/shared/ScrollReveal.tsx"],children:e.jsx("div",{className:"animate-fade-up font-gotham font-[800] text-[18px] text-[#091133]",children:"Fade up"})}),e.jsx(r,{id:"entrance-slide-panel",name:"Panel slide in",status:"active",tech:["css-transition","js-state"],duration:"300 ms",easing:"ease-out",description:"Nav panels (BrandAnimationNavPanel, DevComponentsNavPanel) slide in from the left via translateX(-100%) â translateX(0). Backdrop blur reveals on open.",note:"Spring easing (cubic-bezier(0.16,1,0.3,1)) recommended over ease-out for a more physical feel.",files:["src/components/shared/BrandAnimationNavPanel.tsx","src/components/shared/DevComponentsNavPanel.tsx"],children:e.jsx(W,{})}),e.jsx(r,{id:"entrance-scale-modal",name:"Scale + fade (modal)",status:"active",tech:["tailwindcss-animate"],duration:"200 ms",easing:"ease-out",description:"Radix Dialog/Sheet overlays use tailwindcss-animate's data-[state=open]:animate-in / data-[state=closed]:animate-out for scale-95â100 + fade. Used in NavMobile sheet.",files:["src/components/layout/Navbar.tsx"],children:e.jsx("div",{className:"animate-in fade-in zoom-in-95 duration-200 rounded-[12px] bg-[rgba(207,243,255,0.5)] px-6 py-4 font-gotham font-[800] text-[14px] text-[#091133]",children:"Scale in"})}),e.jsx(r,{id:"entrance-stagger",name:"Stagger cascade",status:"active",tech:["tailwind-keyframe","intersection-observer"],duration:"500 ms + 100â500 ms delay",easing:"ease-out",description:"Multiple ScrollReveal children inside .stagger-children receive nth-child transition-delay offsets (0, 100, 200, 300, 400, 500 ms) creating a cascade entrance.",files:["src/index.css","src/components/shared/ScrollReveal.tsx"],children:e.jsx(U,{})})]})}),e.jsx(h,{id:"scroll-reveal-section",title:"Scroll-driven",intro:"Animations driven by scroll position or viewport intersection. Fluree uses two patterns: threshold-based IO triggers (once-only entrance) and continuous scroll-fraction masks.",children:e.jsxs("div",{className:"grid gap-4 md:grid-cols-2 xl:grid-cols-3",children:[e.jsx(r,{id:"scroll-viewport-reveal",name:"Viewport reveal (ScrollReveal)",status:"active",tech:["intersection-observer","css-transition"],duration:"500 ms",easing:"ease-out",description:"The site's primary scroll animation. IntersectionObserver at threshold 0.15 adds .visible class which drives opacity + transform transition. Fires once per element.",files:["src/components/shared/ScrollReveal.tsx"],children:e.jsx(z,{})}),e.jsx(r,{id:"scroll-stagger-cascade",name:"Stagger on scroll",status:"active",tech:["intersection-observer","css-transition"],duration:"500 ms + delay cascade",easing:"ease-out",description:"Children inside .stagger-children receive nth-child delay offsets (0â500 ms in 100 ms steps). When the parent enters the viewport, children cascade in sequence.",files:["src/index.css","src/components/shared/ScrollReveal.tsx"],children:e.jsx($,{})}),e.jsx(r,{id:"scroll-mask-fade",name:"Scroll-fraction mask fade",status:"active",tech:["scroll-event","css-transition"],duration:"Continuous (tied to scroll fraction)",easing:"linear",description:"WhyFluree uses useScrollFade â a hook that maps scroll position to a mask-image gradient, clipping content as the user scrolls through the section. Creates a depth reveal effect.",files:["src/components/shared/WhyFluree.tsx"],children:e.jsx(K,{})}),e.jsx(r,{id:"scroll-progress-bar",name:"Reading progress bar",status:"active",tech:["scroll-event"],duration:"Continuous",easing:"linear",description:"Blog posts render a 3px cyan progress bar fixed to the top of the viewport. Width is computed as scrollY / (scrollHeight - innerHe
1ight) à 100%.",files:["src/pages/BlogPost.tsx"],children:e.jsx(Y,{})})]})}),e.jsx(h,{id:"nav-tabs",title:"Navigation & Transitions",intro:"State transitions driven by user navigation â tab switching, menu open/close, overlay reveal, and route-level changes.",children:e.jsxs("div",{className:"grid gap-4 md:grid-cols-2 xl:grid-cols-3",children:[e.jsx(r,{id:"nav-tab-switching",name:"Tab content crossfade",status:"inconsistent",tech:["js-state","css-transition"],duration:"150 ms out / 300 ms in",easing:"ease-out",note:"Exit uses duration-150, entrance uses duration-300. Standardize both to duration-200.",description:"EvaluateShipDefend and HowItWorksStage fade tab content out then fade new content in. Implemented via React state + Tailwind opacity + translate-y transitions.",files:["src/components/shared/EvaluateShipDefend.tsx","src/components/shared/HowItWorksStage.tsx"],children:e.jsx(A,{})}),e.jsx(r,{id:"nav-drawer-mobile",name:"Mobile nav drawer",status:"active",tech:["tailwindcss-animate"],duration:"200 ms",easing:"ease-out",description:"Navbar mobile menu uses Radix Sheet â slides in from the right via tailwindcss-animate data-[state=open]:slide-in-from-right-full.",files:["src/components/layout/Navbar.tsx"],children:e.jsx("div",{className:"animate-in slide-in-from-right-8 duration-200 w-40 rounded-[12px] bg-[rgba(207,243,255,0.5)] p-4 font-gotham font-[800] text-[13px] text-[#091133]",children:"Drawer slides in"})}),e.jsx(r,{id:"nav-overlay-entry",name:"Mega-menu overlay",status:"active",tech:["css-transition","js-state"],duration:"300 ms",easing:"ease-out",description:"Desktop nav mega-menus (Solutions, Products) open with opacity + translateY from -8px to 0. Triggered by hover/focus on the parent nav item.",files:["src/components/layout/Navbar.tsx"],children:e.jsx("div",{className:"animate-fade-up duration-300 rounded-[12px] bg-white/80 p-4 shadow-[0_8px_32px_rgba(9,17,51,0.08)] font-gotham font-[800] text-[13px] text-[#091133]",children:"Mega menu reveals"})}),e.jsx(r,{id:"nav-route-transitions",name:"Route transitions",status:"missing",tech:["js-state"],duration:"â",easing:"â",description:"Currently there are no cross-route page transitions. Routes swap instantly inside the Suspense boundary. The Suspense fallback (white div) briefly flashes on slow nav.",note:"Recommended: add a shared layout wrapper with opacity fade (200 ms) on route change. Pair with the idle route prefetcher already in place.",files:["src/App.tsx"],children:e.jsxs("div",{className:"flex items-center gap-3 font-gotham-narrow text-[13px] text-[#9b3a23]",children:[e.jsx(T,{className:"h-5 w-5"}),"No transition defined"]})})]})}),e.jsx(h,{id:"ambient-loop",title:"Continuous / Ambient",intro:"Always-running background animations. Should be subtle enough not to compete with content. All must respect prefers-reduced-motion.",children:e.jsxs("div",{className:"grid gap-4 md:grid-cols-2 xl:grid-cols-3",children:[e.jsx(r,{id:"ambient-marquee",name:"Marquee ticker",status:"inconsistent",tech:["css-keyframe"],duration:"40 s",easing:"linear",note:"Defined twice â @keyframes marquee in index.css AND a 'ticker' keyframe in tailwind.config. Consolidate to one source of truth.",description:"CustomerStoriesRail logo marquee. Two copies of the content track side-by-side; the animation translates -50% to create a seamless loop. No prefers-reduced-motion guard.",files:["src/components/shared/CustomerStoriesRail.tsx","src/index.css","tailwind.config.ts"],children:e.jsx("div",{className:"overflow-hidden w-full",children:e.jsxs("div",{className:"flex whitespace-nowrap animate-marquee",children:[e.jsx("span",{className:"px-6 font-gotham font-[900] text-[14px] text-[#091133]",children:"Fluree · GraphRAG · Knowledge Graphs · Semantic Layer · "}),e.jsx("span",{className:"px-6 font-gotham font-[900] text-[14px] text-[#091133]",children:"Fluree · GraphRAG · Knowledge Graphs · Semantic Layer · "})]})})}),e.jsx(r,{id:"ambient-float",name:"Float / bob",status:"active",tech:["tailwind-keyframe"],duration:"3 s",easing:"ease-in-out",description:"Decorative elements (hero illustrations, floating badges) bob up and down 6p
1x via the float keyframe. Creates a gentle breathing feel without visual noise.",files:["tailwind.config.ts"],children:e.jsx("div",{className:"animate-float h-12 w-12 rounded-full bg-[#13c6ff] shadow-[0_0_20px_rgba(19,198,255,0.4)]"})}),e.jsx(r,{id:"ambient-pulse",name:"Pulse / heartbeat",status:"active",tech:["tailwind-keyframe"],duration:"2 s",easing:"ease-in-out",description:"Small indicator dots and data-state highlights use animate-pulse-teal to cycle between 40% and 100% opacity. Signals live data or active state.",files:["tailwind.config.ts"],children:e.jsx("div",{className:"animate-pulse-teal h-3 w-3 rounded-full bg-[#13c6ff]"})}),e.jsx(r,{id:"ambient-svg-flow",name:"SVG stroke flow",status:"active",tech:["css-keyframe","svg-inline"],duration:"3.6 s",easing:"linear",description:"FlureeGraphStory and knowledge-graph SVG scenes animate stroke-dashoffset to draw paths and flow data through edges. Uses animate-pulse-flow from index.css.",files:["src/index.css","src/components/shared/fluree-graph/"],children:e.jsxs("svg",{viewBox:"0 0 180 60",className:"h-[60px] w-[180px]",children:[e.jsx("path",{d:"M5,30 Q90,5 175,30",fill:"none",stroke:"#13c6ff",strokeWidth:"2",strokeDasharray:"6 16",className:"animate-pulse-flow"}),e.jsx("circle",{cx:"5",cy:"30",r:"4",fill:"#13c6ff",opacity:"0.5"}),e.jsx("circle",{cx:"175",cy:"30",r:"4",fill:"#4b57a5",opacity:"0.5"})]})})]})}),e.jsx(h,{id:"seq-hero",title:"Orchestrated Sequences",intro:"Multi-step animations that coordinate several elements in a timed sequence. Requires careful choreography â each element's timing must be intentional.",children:e.jsxs("div",{className:"grid gap-4 md:grid-cols-2 xl:grid-cols-3",children:[e.jsx(r,{id:"seq-hero-entrance",name:"Hero entrance sequence",status:"active",tech:["tailwind-keyframe","js-state"],duration:"500â800 ms (staggered)",easing:"ease-out",description:"ProductHero mounts with a sequence: eyebrow fades first (0 ms delay), then H1 (100 ms), then body copy (200 ms), then CTAs (300 ms). All use animate-fade-up.",files:["src/components/shared/ProductHero.tsx"],children:e.jsx(Q,{})}),e.jsx(r,{id:"seq-graph-scene",name:"Knowledge graph scene",status:"active",tech:["requestAnimationFrame","svg-inline"],duration:"Continuous (rAF loop)",easing:"linear",description:"FlureeGraphStory runs a requestAnimationFrame canvas loop rendering nodes, edges, and particle flows. Nodes pulse on hover, edges draw via strokeDashoffset animation.",files:["src/components/shared/fluree-graph/FlureeGraphStory.tsx"],children:e.jsxs("div",{className:"font-gotham-narrow text-[12px] text-[#4b57a5] text-center",children:[e.jsxs("div",{className:"mb-2 flex items-center justify-center gap-3",children:[e.jsx("div",{className:"animate-pulse-teal h-3 w-3 rounded-full bg-[#13c6ff]"}),e.jsx("div",{className:"h-px w-12 border-t-2 border-dashed border-[#13c6ff]"}),e.jsx("div",{className:"animate-pulse-teal h-3 w-3 rounded-full bg-[#4b57a5]",style:{animationDelay:"0.5s"}}),e.jsx("div",{className:"h-px w-12 border-t-2 border-dashed border-[#13c6ff]"}),e.jsx("div",{className:"animate-pulse-teal h-3 w-3 rounded-full bg-[#13c6ff]",style:{animationDelay:"1s"}})]}),"Canvas rAF loop (view at /solutions/enterprise-knowledge-graph)"]})}),e.jsx(r,{id:"seq-multi-step",name:"Multi-step how-it-works",status:"active",tech:["js-state","css-transition","intersection-observer"],duration:"300 ms per step",easing:"ease-out",description:"HowItWorksStage auto-advances through 3 steps with a timed interval. Each step fades in its content panel and animates the step indicator. IO pauses the interval while offscreen.",files:["src/components/shared/HowItWorksStage.tsx"],children:e.jsx(X,{})})]})}),e.jsx(h,{id:"data-graph",title:"Data Visualization",intro:"Animations that represent data structure, flow, or change over time. These require special care â motion must clarify, not decorate.",children:e.jsxs("div",{className:"grid gap-4 md:grid-cols-2 xl:grid-cols-3",children:[e.jsx(r,{id:"data-graph-network",name:"Graph / network canvas",status:"active",tech:["requestAnimationFrame"],duration:"Continuous (60 fps)",easing:"linear",description:"FlureeGraphStory renders a knowledge graph with animated nodes and directional edges on a canvas element. Particle effects flow along edges to show data movement.",files:["src/components/shared/fluree-graph/FlureeGraphStory.tsx","src/components/shared/fluree-graph/"],children:e.jsxs("div",{className:"font-gotham-narrow text-[12px] text-[#4b57a5] text-center",children:["Canvas animation â visit"," ",e.jsx("a",{href:"/solutions/enterprise-knowledge-graph",className:"text-[#0a7da3] underline",target:"_blank",rel:"noopener noreferrer",children:"enterprise-knowledge-graph"})," ","to see live"]})}),e.jsx(r,{id:"data-bar-chart",name:"Animated bar chart",status:"active",tech:["css-transition","js-state"],duration:"600â800 ms",easing:"ease-out",description:"AIReadinessAssessment accuracy benchmark uses CSS height transitions on bar elements. Bars grow from 0 to their target height when the section scrolls into view.",files:["src/components/shared/AIReadinessAssessment.tsx"],children:e.jsx(J,{})}),e.jsx(r,{id:"data-progress-ring",name:"SVG stroke progress",status:"recommended",tech:["svg-inline","css-transition"],duration:"600 ms",easing:"ease-out",description:"RECOMMENDED pattern for future metric displays: SVG circle with stroke-dasharray/dashoffset animated on scroll reveal. More expressive than bar charts for percentages.",note:"Not yet deployed in production. Propose for case study metric sections.",files:[],children:e.jsx(Z,{})})]})}),e.jsx(h,{id:"sys-modal",title:"System / Overlay",intro:"Animations for UI system elements: modals, accordions, toasts, tooltips. These use tailwindcss-animate (via Radix primitives) for Radix-owned overlays, and custom CSS for brand-owned patterns.",children:e.jsxs("div",{className:"grid gap-4 md:grid-cols-2 xl:grid-cols-3",children:[e.jsx(r,{id:"sys-modal-dialog",name:"Modal / dialog",status:"active",tech:["tailwindcss-animate"],duration:"200 ms",easing:"ease-out",description:"Radix Dialog uses tailwindcss-animate data-[state=open]:animate-in with fade-in + zoom-in-95. The overlay fades separately. Controlled by Radix's state machine.",files:["src/components/ui/dialog.tsx"],children:e.jsx("div",{className:"animate-in fade-in zoom-in-95 duration-200 rounded-[16px] bg-white/90 px-6 py-4 shadow-[0_8px_40px_rgba(9,17,51,0.12)] font-gotham font-[800] text-[14px] text-[#091133]",children:"Dialog appears"})}),e.jsx(r,{id:"sys-accordion",name:"Accordion expand / collapse",status:"active",tech:["tailwindcss-animate"],duration:"200 ms",easing:"ease-out",description:"Radix Accordion uses tailwindcss-animate accordion-down / accordion-up keyframes that animate height via CSS custom property --radix-accordion-content-height.",files:["tailwind.config.ts","src/components/ui/accordion.tsx"],children:e.jsx(ee,{})}),e.jsx(r,{id:"sys-toast",name:"Toast / notification",status:"active",tech:["tailwindcss-animate"],duration:"200 ms",easing:"ease-out",description:"Sonner toast notifications use tailwindcss-animate slide-in-from-bottom + fade-in for entry. Exit uses slide-out-to-right-full + fade-out.",files:["src/components/ui/sonner.tsx"],children:e.jsx("div",{className:"animate-in slide-in-from-bottom-4 fade-in duration-200 rounded-[10px] bg-[#091133] px-4 py-3 font-gotham-narrow text-[13px] text-white shadow-[0_4px_20px_rgba(9,17,51,0.24)]",children:"Toast notification"})}),e.jsx(r,{id:"sys-tooltip",name:"Tooltip",status:"active",tech:["tailwindcss-animate"],duration:"200 ms",easing:"ease-out",description:"Radix Tooltip uses tailwindcss-animate fade-in + zoom-in-95 on open. Used sparingly â primarily for icon-only buttons that require labeling.",files:["src/components/ui/tooltip.tsx"],children:e.jsx("div",{className:"animate-in fade-in zoom-in-95 duration-200 rounded-[6px] bg-[#091133] px-3 py-1.5 font-gotham-narrow text-[12px] text-white shadow-[0_4px_12px_rgba(9,17,51,0.2)]",children:"Tooltip label"})})]})})]})})})]})};function L(){const[t,s]=o.useState(!1);return e.jsxs("button",{type:"button",onClick:()=>s(a=>!a),className:"inline-flex items-center gap-2 font-gotham-narrow text-[14px] text-[#091133]",children:["Toggle category",e.jsx("svg",{className:d("h-4 w-4 transition-transform duration-200",!t&&"-rotate-90"),viewBox:"0 0 16 16",fill:"none",children:e.jsx("path",{d:"M4 6l4 4 4-4",stroke:"currentColor",strokeWidth:"1.5",strokeLinecap:"round",strokeLinejoin:"round"})})]})}function A(){const[t,s]=o.useState("a");return e.jsxs("div",{className:"w-full",children:[e.jsx("div",{className:"mb-3 flex gap-2",children:["a","b"].map(a=>e.jsxs("button",{type:"button",onClick:()=>s(a),className:d("rounded-full px-4 py-1.5 font-gotham font-[800] text-[12px] transition-all duration-200",t===a?"bg-[#13c6ff] text-[#091133]":"bg-[rgba(207,243,255,0.4)] text-[#4b57a5] hover:bg-[rgba(19,198,255,0.2)]"),children:["Tab ",a.toUpperCase()]},a))}),e.jsxs("div",{className:"relative h-10",children:[e.jsx("div",{className:d("absolute inset-0 flex items-center font-gotham-narrow text-[13px] text-[#091133] transition-all",t==="a"?"opacity-100 translate-y-0 duration-300":"opacity-0 -translate-y-1 duration-150 pointer-events-none"),children:"Content for Tab A"}),e.jsx("div",{className:d("absolute inset-0 flex items-center font-gotham-narrow text-[13px] text-[#091133] transition-all",t==="b"?"opacity-100 translate-y-0 duration-300":"opacity-0 translate-y-1 duration-150 pointer-events-none"),children:"Content for Tab B"})]})]})}function W(){const[t,s]=o.useState(!1);return e.jsxs("div",{className:"relative w-full overflow-hidden h-20",children:[e.jsx("button",{type:"button",onClick:()=>s(a=>!a),className:"rounded-full border border-[rgba(19,198,255,0.5)] bg-[rgba(207,243,255,0.5)] px-4 py-1.5 font-operator font-[700] text-[10px] uppercase tracking-[1.4px] text-[#091133] hover:bg-[rgba(19,198,255,0.2)] transition-colors",children:t?"Close panel":"Open panel"}),e.jsx("div",{className:d("absolute left-0 top-0 h-full w-40 rounded-[10px] bg-[rgba(207,243,255,0.8)] p-3 shadow-[0_4px_20px_rgba(9,17,51,0.1)] transition-transform duration-300 ease-out",t?"translate-x-0":"-translate-x-full"),children:e.jsx("p",{className:"font-gotham font-[800] text-[11px] text-[#091133]",children:"Panel content"})})]})}function U(){return e.jsx("div",{className:"stagger-children flex flex-col gap-2 w-full",children:["First","Second","Third"].map((t,s)=>e.jsxs("div",{className:"scroll-reveal visible rounded-[6px] bg-[rgba(207,243,255,0.4)] px-3 py-2 font-gotham-narrow text-[12px] text-[#091133] transition-all duration-500 ease-out",style:{transitionDelay:`${s*100}ms`},children:[t," item"]},t))})}function $(){const[t,s]=o.useState(!1),a=o.useRef(null);return o.useEffect(()=>{const i=a.current;if(!i)return;const n=new IntersectionObserver(([c])=>{c.isIntersecting&&s(!0)},{threshold:.3});return n.observe(i),()=>n.disconnect()},[]),e.jsx("div",{ref:a,className:"flex flex-col gap-2 w-full",children:["Item one","Item two","Item three"].map((i,n)=>e.jsx("div",{className:"rounded-[6px] bg-[rgba(207,243,255,0.4)] px-3 py-2 font-gotham-narrow text-[12px] text-[#091133] transition-all duration-500 ease-out",style:{opacity:t?1:0,transform:t?"translateY(0)":"translateY(12px)",transitionDelay:t?`${n*120}ms`:"0ms"},children:i},i))})}function K(){const[t,s]=o.useState(40);return e.jsxs("div",{className:"flex flex-col items-center gap-3 w-full",children:[e.jsx("div",{className:"w-full h-16 rounded-[8px] bg-gradient-to-b from-[#091133] to-[#4b57a5] transition-all duration-150",style:{WebkitMaskImage:`linear-gradient(to bottom, transparent ${t}%, black ${t+20}%)`,maskImage:`linear-gradient(to bottom, transparent ${t}%, black ${t+20}%)`}}),e.jsx("input",{type:"range",min:0,max:80,value:t,onChange:a=>s(Number(a.target.value)),className:"w-full accent-[#13c6ff]","aria-label":"Mask position"}),e.jsx("p",{className:"font-operator text-[10px] text-[#4b57a5]",children:"Drag to simulate scroll fraction"})]})}function Y(){const[t,s]=o.useState(45);return e.jsxs("div",{className:"flex flex-col items-center gap-3 w-full",children:[e.jsx("div",{className:"relative w-full h-[3px] rounded bg-[rgba(19,198,255,0.2)]",children:e.jsx("div",{className:"absolute left-0 top-0 h-full rounded bg-[#13c6ff] transition-all duration-150",style:{width:`${t}%`}})}),e.jsx("input",{type:"range",min:0,max:100,value:t,onChange:a=>s(Number(a.target.value)),className:"w-full accent-[#13c6ff]","aria-label":"Progress"}),e.jsxs("p",{className:"font-operator text-[10px] text-[#4b57a5]",children:["Simulated reading progress (",t,"%)"]})]})}function Q(){return e.jsxs("div",{className:"flex flex-col gap-2 w-full",children:[e.jsx("div",{className:"animate-fade-up font-operator text-[10px] uppercase tracking-[1.4px] text-[#4b57a5]",style:{animationDelay:"0ms"},children:"Eyebrow label"}),e.jsx("div",{className:"animate-fade-up font-gotham font-[800] text-[18px] text-[#091133]",style:{animationDelay:"100ms",animationFillMode:"both"},children:"Hero heading"}),e.jsx("div",{className:"animate-fade-up font-gotham-narrow text-[12px] text-[#202152]",style:{animationDelay:"200ms",animationFillMode:"both"},children:"Subtitle copy text"}),e.jsx("div",{className:"animate-fade-up",style:{animationDelay:"300ms",animationFillMode:"both"},children:e.jsx("span",{className:"inline-flex rounded-full bg-[#13c6ff] px-3 py-1 font-gotham font-[800] text-[11px] text-[#091133]",children:"CTA button"})})]})}function X(){const[t,s]=o.useState(0);o.useEffect(()=>{const i=setInterval(()=>s(n=>(n+1)%3),2e3);return()=>clearInterval(i)},[]);const a=["Connect sources","Build knowledge graph","Query with AI"];return e.jsxs("div",{className:"flex flex-col gap-3 w-full",children:[e.jsx("div",{className:"flex gap-2",children:a.map((i,n)=>e.jsx("div",{className:d("h-1.5 flex-1 rounded-full transition-all duration-300",n===t?"bg-[#13c6ff]":"bg-[rgba(19,198,255,0.2)]")},n))}),e.jsx("div",{className:"relative h-8",children:a.map((i,n)=>e.jsxs("div",{className:d("absolute inset-0 flex items-center font-gotham font-[800] text-[13px] text-[#091133] transition-all duration-300",n===t?"opacity-100 translate-y-0":"opacity-0 translate-y-1 pointer-events-none"),children:[n+1,". ",i]},i))})]})}function J(){const[t,s]=o.useState(!1),a=o.useRef(null);o.useEffect(()=>{const n=a.current;if(!n)return;const c=new IntersectionObserver(([m])=>{m.isIntersecting&&s(!0)},{threshold:.3});return c.observe(n),()=>c.disconnect()},[]);const i=[{pct:20,label:"SQL RAG",color:"bg-[rgba(255,87,64,0.5)]"},{pct:60,label:"Vector RAG",color:"bg-[rgba(255,164,0,0.5)]"},{pct:95,label:"GraphRAG",color:"bg-[#13c6ff]"}];return e.jsx("div",{ref:a,className:"flex items-end gap-4",children:i.map(n=>e.jsxs("div",{className:"flex flex-col items-center gap-1",children:[e.jsx("div",{className:"h-20 flex items-end justify-center",children:e.jsx("div",{className:d("w-8 rounded-t-lg transition-all duration-700 ease-out",n.color),style:{height:t?`${n.pct}%`:"0%"}})}),e.jsx("p",{className:"font-operator text-[9px] text-[#202152] text-center",children:n.label})]},n.label))})}function Z(){const[t,s]=o.useState(!1),a=o.useRef(null);o.useEffect(()=>{const p=a.current;
1if(!p)return;const g=new IntersectionObserver(([v])=>{v.isIntersecting&&s(!0)},{threshold:.3});return g.observe(p),()=>g.disconnect()},[]);const i=28,n=2*Math.PI*i,c=95,m=n-c/100*n;return e.jsxs("div",{ref:a,className:"flex flex-col items-center gap-2",children:[e.jsxs("svg",{width:"72",height:"72",viewBox:"0 0 72 72",children:[e.jsx("circle",{cx:"36",cy:"36",r:i,fill:"none",stroke:"rgba(19,198,255,0.15)",strokeWidth:"6"}),e.jsx("circle",{cx:"36",cy:"36",r:i,fill:"none",stroke:"#13c6ff",strokeWidth:"6",strokeLinecap:"round",strokeDasharray:n,strokeDashoffset:t?m:n,style:{transition:"stroke-dashoffset 0.8s ease-out",transform:"rotate(-90deg)",transformOrigin:"50% 50%"}}),e.jsxs("text",{x:"36",y:"40",textAnchor:"middle",className:"font-gotham",fontSize:"14",fontWeight:"800",fill:"#091133",children:[c,"%"]})]}),e.jsx("p",{className:"font-operator text-[10px] text-[#4b57a5]",children:"Recommended pattern"})]})}function ee(){const[t,s]=o.useState(!1);return e.jsxs("div",{className:"w-full",children:[e.jsxs("button",{type:"button",onClick:()=>s(a=>!a),className:"flex w-full items-center justify-between rounded-[8px] bg-[rgba(207,243,255,0.4)] px-4 py-3 font-gotham font-[800] text-[13px] text-[#091133] hover:bg-[rgba(19,198,255,0.15)] transition-colors",children:["Accordion item",e.jsx("svg",{className:d("h-4 w-4 transition-transform duration-200",t&&"rotate-180"),viewBox:"0 0 16 16",fill:"none",children:e.jsx("path",{d:"M4 6l4 4 4-4",stroke:"currentColor",strokeWidth:"1.5",strokeLinecap:"round",strokeLinejoin:"round"})})]}),e.jsx("div",{className:"overflow-hidden transition-all duration-200 ease-out",style:{maxHeight:t?"120px":"0px"},children:e.jsx("div",{className:"px-4 py-3 font-gotham-narrow text-[12px] text-[#202152]",children:"Expanded content animates height via max-height transition. The Radix version uses CSS custom property height."})})]})}export{le as default};
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.