diff --git a/apps/dashboard/src/app/globals.css b/apps/dashboard/src/app/globals.css index 01323f24..3e52ce32 100644 --- a/apps/dashboard/src/app/globals.css +++ b/apps/dashboard/src/app/globals.css @@ -13,21 +13,6 @@ * growing the document (monitor logs) subtract both. */ --spacing-app-header: 3.5rem; --spacing-app-tabs: 41px; - - /* A 0.3s hold, then a 0.3s half-turn, on repeat. The mark is symmetric under - * a half turn, so every cycle ends where it visually began and the loop never - * jumps. ease-in-out because a linear turn that stops dead looks broken. */ - --animate-spin-half: spin-half 0.6s ease-in-out infinite; - - @keyframes spin-half { - 0%, - 50% { - transform: rotate(0deg); - } - 100% { - transform: rotate(180deg); - } - } } @theme inline { diff --git a/apps/dashboard/src/app/loading.tsx b/apps/dashboard/src/app/loading.tsx index 394d8e11..5b41efcd 100644 --- a/apps/dashboard/src/app/loading.tsx +++ b/apps/dashboard/src/app/loading.tsx @@ -1,9 +1,9 @@ -import { OpenStatusIcon } from "@openstatus/icons/brand"; +import { OpenStatusLoadingIcon } from "@openstatus/icons/brand"; export default function RootLoading() { return (
- + Loading
); diff --git a/packages/icons/src/brand/openstatus.tsx b/packages/icons/src/brand/openstatus.tsx index da4b076f..77c2a4af 100644 --- a/packages/icons/src/brand/openstatus.tsx +++ b/packages/icons/src/brand/openstatus.tsx @@ -27,3 +27,95 @@ export function OpenStatusIcon(props: React.ComponentProps<"svg">) { ); } + +/** + * The mark as a loading indicator, told as a round-trip check. The cycle opens + * on the complete S and holds, so a fast load only ever shows the static mark + * and the swap from the plain icon is seamless. Then both slits wipe forward + * and clear, the top slit shoots from the center out the right rim, a short + * latency gap, the bottom slit comes in from the left rim to the center, and + * the whole mark thumps once as the response lands, back into the hold. The + * thump is delayed by one full cycle so the very first frame is still. + * Each keyframe sets the easing of the segment it starts: travel settles into + * its destination, the clear accelerates away. The thump overshoots the box, + * so overflow is visible and the icon keeps the static mark's footprint. + * Animates rect geometry directly; the static attributes are the resting mark, + * so reduced motion and older engines fall back to the plain icon. + */ +export function OpenStatusLoadingIcon(props: React.ComponentProps<"svg">) { + return ( + + openstatus + + + + + + + + + + + ); +}