From 68406563c1e2273e72eaeeb610d7c49e828a671c Mon Sep 17 00:00:00 2001 From: seminalworks <91576302+seminalworks@users.noreply.github.com> Date: Wed, 19 Aug 2026 02:00:04 -0700 Subject: [PATCH] Fix AI Workspace loader animation not rendering in Safari The gooey blob effect relied on CSS blur()/contrast() filters applied to content referenced via a CSS mask, which Safari doesn't reliably render. Replaced the mask-based approach with a native SVG filter (feGaussianBlur + feColorMatrix) applied directly to the visible shapes, which renders consistently across Chrome, Safari, and Firefox. Also fixes a layout regression (loader collapsing to zero height, causing text to overlap it) and pins the SVG's absolute position explicitly instead of relying on browser-guessed static positioning. Ported from apim-saas PR #2912 following the migration to this repo. Co-Authored-By: Claude Sonnet 5 --- .../ai-workspace/src/Components/AILoader.tsx | 48 +++++++++++++++---- portals/ai-workspace/src/styles.css | 46 +++--------------- 2 files changed, 45 insertions(+), 49 deletions(-) diff --git a/portals/ai-workspace/src/Components/AILoader.tsx b/portals/ai-workspace/src/Components/AILoader.tsx index 434377f327..e918d43f4f 100644 --- a/portals/ai-workspace/src/Components/AILoader.tsx +++ b/portals/ai-workspace/src/Components/AILoader.tsx @@ -26,18 +26,46 @@ export default function AILoader({ label }: AILoaderProps) {
- - - - - - - - - + + + + + + + + + + + + + + + + + -
); } diff --git a/portals/ai-workspace/src/styles.css b/portals/ai-workspace/src/styles.css index 5e9d10a7e9..ef224cc894 100644 --- a/portals/ai-workspace/src/styles.css +++ b/portals/ai-workspace/src/styles.css @@ -98,6 +98,8 @@ body { --size: 1; position: relative; + width: 100px; + height: 100px; border-radius: 50%; transform: scale(var(--size)); @@ -121,29 +123,13 @@ body { inset 0 -10px 10px 0 var(--color-four); } -.loader .box { - width: 100px; - height: 100px; - background: linear-gradient( - 180deg, - var(--color-one) 30%, - var(--color-two) 70% - ); - mask: url(#clipping); - -webkit-mask: url(#clipping); -} - .loader svg { position: absolute; -} - -.loader svg #clipping { - filter: contrast(15); - animation: roundness calc(var(--time-animation) / 2) linear infinite; -} - -.loader svg #clipping polygon { - filter: blur(7px); + top: 0; + left: 0; + display: block; + transform: translateZ(0); + will-change: filter; } .loader svg #clipping polygon:nth-child(1) { @@ -193,24 +179,6 @@ body { } } -@keyframes roundness { - 0% { - filter: contrast(15); - } - 20% { - filter: contrast(3); - } - 40% { - filter: contrast(3); - } - 60% { - filter: contrast(15); - } - 100% { - filter: contrast(15); - } -} - @keyframes colorize { 0% { filter: hue-rotate(0deg);