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 (
+
+ );
+}