import { keyframes, style } from '@vanilla-extract/css'; import { config } from 'folds'; // One sweep, left → right. The bar is full-viewport-wide; the radial gradient // fades to transparent at both edges, so the keyframe loop from // `translateX(100%)` back to `translateX(-100%)` happens entirely off-screen // and the snap is invisible. const slide = keyframes({ '0%': { transform: 'translateX(-100%)' }, '100%': { transform: 'translateX(100%)' }, }); // Container is taller than the visible bar so the drop-shadow halo isn't // clipped by `overflow: hidden`. The bar itself sits flush to the bottom // edge of the safe-area inset (the 26px above is a transparent // pointer-events: none zone where only the glow renders). export const root = style({ position: 'fixed', left: 'env(safe-area-inset-left, 0px)', right: 'env(safe-area-inset-right, 0px)', bottom: 'env(safe-area-inset-bottom, 0px)', height: '28px', pointerEvents: 'none', // Z400 sits above app chrome and below folds modals/popouts (which use // Max=9999). Connection state should be visible on the page, not over // dialogs. zIndex: config.zIndex.Z400, overflow: 'hidden', }); const barBase = style({ position: 'absolute', bottom: 0, left: 0, width: '100%', height: '2px', // 250ms opacity transition carries progress↔hidden and progress↔error // crossfades smoothly. Both layers are always mounted; the React side // toggles opacity. transition: 'opacity 250ms ease', }); export const barProgress = style([ barBase, { background: 'radial-gradient(ellipse 50% 100% at center, #5BE3C5 0%, rgba(91, 227, 197, 0.45) 35%, rgba(91, 227, 197, 0) 70%)', filter: 'drop-shadow(0 0 6px rgba(91, 227, 197, 0.8))', animation: `${slide} 1.8s linear infinite`, willChange: 'transform', '@media': { '(prefers-reduced-motion: reduce)': { animation: 'none', }, }, }, ]); export const barError = style([ barBase, { // Slightly brighter, denser-fade red — the gradient extends closer to // the viewport edges than the green sweep so the static error visual // reads as a stronger statement than the moving progress one. Same // 2px height as the progress bar. background: 'radial-gradient(ellipse 50% 100% at center, #FF3030 0%, rgba(255, 48, 48, 0.7) 50%, rgba(255, 48, 48, 0) 90%)', filter: 'drop-shadow(0 0 12px rgba(255, 48, 48, 0.95))', }, ]);