diff --git a/src/components/common/messaging/attachments/TextFile.tsx b/src/components/common/messaging/attachments/TextFile.tsx
index 810a2f0b0f76636bd71270625e5609e9ac83d74d..c01976f566eafdce373b322ddb9856b497d4f5c1 100644
--- a/src/components/common/messaging/attachments/TextFile.tsx
+++ b/src/components/common/messaging/attachments/TextFile.tsx
@@ -49,7 +49,7 @@ export default function TextFile({ attachment }: Props) {
                 content ?
                     <pre><code>{ content }</code></pre>
                     : <RequiresOnline>
-                        <Preloader />
+                        <Preloader type="ring" />
                     </RequiresOnline>
             }
         </div>
diff --git a/src/components/ui/Preloader.tsx b/src/components/ui/Preloader.tsx
index 4f92146c689784e3bc8b52fea4774335f96a933e..7e3ec3fcda41739da3f21da363f692a212d1aeda 100644
--- a/src/components/ui/Preloader.tsx
+++ b/src/components/ui/Preloader.tsx
@@ -1,3 +1,103 @@
-export default function Preloader() {
-    return <span>LOADING</span>;
+import styled, { keyframes } from "styled-components";
+
+const skSpinner = keyframes`
+    0%, 80%, 100% { 
+        -webkit-transform: scale(0);
+        transform: scale(0);
+    }
+    40% { 
+        -webkit-transform: scale(1.0);
+        transform: scale(1.0);
+    }
+`;
+
+const prRing = keyframes`
+    0% {
+        transform: rotate(0deg);
+    }
+    100% {
+        transform: rotate(360deg);
+    }
+`;
+
+const PreloaderBase = styled.div`
+    width: 100%;
+    height: 100%;
+
+    display: grid;
+    place-items: center;
+
+    .spinner {
+        width: 58px;
+        display: flex;
+        text-align: center;
+        margin: 100px auto 0;
+        justify-content: space-between;
+    }
+
+    .spinner > div {
+        width: 14px;
+        height: 14px;
+        background-color: var(--tertiary-foreground);
+
+        border-radius: 100%;
+        display: inline-block;
+        animation: ${skSpinner} 1.4s infinite ease-in-out both;
+    }
+
+    .spinner div:nth-child(1) {
+        animation-delay: -0.32s;
+    }
+
+    .spinner div:nth-child(2) {
+        animation-delay: -0.16s;
+    }
+
+    .ring {
+        display: inline-block;
+        position: relative;
+        width: 48px;
+        height: 52px;
+    }
+
+    .ring div {
+        width: 32px;
+        margin: 8px;
+        height: 32px;
+        display: block;
+        position: absolute;
+        border-radius: 50%;
+        box-sizing: border-box;
+        border: 2px solid #fff;
+        animation: ${prRing} 1.2s cubic-bezier(0.5, 0, 0.5, 1) infinite;
+        border-color: #fff transparent transparent transparent;
+    }
+
+    .ring div:nth-child(1) {
+        animation-delay: -0.45s;
+    }
+
+    .ring div:nth-child(2) {
+        animation-delay: -0.3s;
+    }
+
+    .ring div:nth-child(3) {
+        animation-delay: -0.15s;
+    }
+`;
+
+interface Props {
+    type: 'spinner' | 'ring'
+}
+
+export default function Preloader({ type }: Props) {
+    return (
+        <PreloaderBase>
+            <div class={type}>
+                <div />
+                <div />
+                <div />
+            </div>
+        </PreloaderBase>
+    );
 }
diff --git a/src/context/intermediate/modals/Onboarding.tsx b/src/context/intermediate/modals/Onboarding.tsx
index 032aa5f3771a8782f92b27a70226fd46f41bcc37..8f3894d8c2132af5e3eb96c81cc9ab12212046cf 100644
--- a/src/context/intermediate/modals/Onboarding.tsx
+++ b/src/context/intermediate/modals/Onboarding.tsx
@@ -39,7 +39,7 @@ export function OnboardingModal({ onClose, callback }: Props) {
             </div>
             <div className={styles.form}>
                 {loading ? (
-                    <Preloader />
+                    <Preloader type="spinner" />
                 ) : (
                     <>
                         <p>
diff --git a/src/context/intermediate/popovers/UserProfile.tsx b/src/context/intermediate/popovers/UserProfile.tsx
index 2b37ee7c3aaa802075fab9021b979c2c8e0ac365..2bcddb36edb010804766d5a7f7b9d07cb47a5f8e 100644
--- a/src/context/intermediate/popovers/UserProfile.tsx
+++ b/src/context/intermediate/popovers/UserProfile.tsx
@@ -309,7 +309,7 @@ export function UserProfile({ user_id, onClose, dummy, dummyProfile }: Props) {
                             )}
                         </div>
                     ) : (
-                        <Preloader />
+                        <Preloader type="ring" />
                     ))}
                 {tab === "groups" && (
                     <div className={styles.entries}>
diff --git a/src/context/revoltjs/FileUploads.tsx b/src/context/revoltjs/FileUploads.tsx
index df10fb4c5d885435becb22258b8a874b5cccc8d2..4be51c16647c9f775a638bb1eb82a700977acac5 100644
--- a/src/context/revoltjs/FileUploads.tsx
+++ b/src/context/revoltjs/FileUploads.tsx
@@ -187,7 +187,7 @@ export function FileUploader(props: Props) {
                     onClick={onClick}>
                     { uploading ?
                         <div className={styles.uploading}>
-                            <Preloader />
+                            <Preloader type="ring" />
                         </div> :
                         <div className={styles.edit}>
                             <Edit size={30} />
diff --git a/src/context/revoltjs/RequiresOnline.tsx b/src/context/revoltjs/RequiresOnline.tsx
index 73b7f72199d1bed5a1b6d7d6d9906e0d8c489950..20779e5f21bea6dfd6c45ee3c804fb1444dafbae 100644
--- a/src/context/revoltjs/RequiresOnline.tsx
+++ b/src/context/revoltjs/RequiresOnline.tsx
@@ -29,7 +29,7 @@ const Base = styled.div`
 export default function RequiresOnline(props: Props) {
     const status = useContext(StatusContext);
 
-    if (status === ClientStatus.CONNECTING) return <Preloader />;
+    if (status === ClientStatus.CONNECTING) return <Preloader type="ring" />;
     if (status !== ClientStatus.ONLINE && status !== ClientStatus.READY)
         return (
             <Base>
diff --git a/src/context/revoltjs/RevoltClient.tsx b/src/context/revoltjs/RevoltClient.tsx
index 045b7f9496a9b6c6962de6d8ff45442da8b5eb43..8718ef41fc21276f878856bcc2ba551d2cc020d0 100644
--- a/src/context/revoltjs/RevoltClient.tsx
+++ b/src/context/revoltjs/RevoltClient.tsx
@@ -202,7 +202,7 @@ function Context({ auth, sync, children, dispatcher }: Props) {
     }, []);
 
     if (status === ClientStatus.LOADING) {
-        return <Preloader />;
+        return <Preloader type="spinner" />;
     }
 
     return (
diff --git a/src/pages/RevoltApp.tsx b/src/pages/RevoltApp.tsx
index 53400ce80482a278e8fc260cd32f18eb6693a070..ad93f0c2be0a98559efd2a0e51e21fec6302d97d 100644
--- a/src/pages/RevoltApp.tsx
+++ b/src/pages/RevoltApp.tsx
@@ -34,13 +34,15 @@ const Routes = styled.div`
 export default function App() {
     const path = useLocation().pathname;
     const fixedBottomNav = (path === '/' || path === '/settings' || path.startsWith("/friends"));
+    const inSettings = path === '/settings';
+    const inChannel = path.includes('/channel');
 
     return (
         <OverlappingPanels
             width="100vw"
             height="100vh"
-            leftPanel={{ width: 292, component: <LeftSidebar /> }}
-            rightPanel={{ width: 240, component: <RightSidebar /> }}
+            leftPanel={inSettings ? undefined : { width: 292, component: <LeftSidebar /> }}
+            rightPanel={(!inSettings && inChannel) ? { width: 240, component: <RightSidebar /> } : undefined}
             bottomNav={{
                 component: <BottomNavigation />,
                 showIf: fixedBottomNav ? ShowIf.Always : ShowIf.Left,
diff --git a/src/pages/app.tsx b/src/pages/app.tsx
index c6af90ae91976c8a94d913660980fc9ea2a5f850..d77f32e3cec4b68bc0cf738ecd4fc6bf8b70a921 100644
--- a/src/pages/app.tsx
+++ b/src/pages/app.tsx
@@ -12,7 +12,7 @@ export function App() {
         <Context>
             {/* 
             // @ts-expect-error */}
-            <Suspense fallback={<Preloader />}>
+            <Suspense fallback={<Preloader type="spinner" />}>
                 <Switch>
                     <Route path="/login">
                         <CheckAuth>
diff --git a/src/pages/channels/messaging/MessageArea.tsx b/src/pages/channels/messaging/MessageArea.tsx
index 6e609662a324560480a36cf370be85639188dd31..a178fab821519e614f6f19a289961181c052bf46 100644
--- a/src/pages/channels/messaging/MessageArea.tsx
+++ b/src/pages/channels/messaging/MessageArea.tsx
@@ -215,10 +215,10 @@ export function MessageArea({ id }: Props) {
         <MessageAreaWidthContext.Provider value={(width ?? 0) - MESSAGE_AREA_PADDING}>
             <Area ref={ref}>
                 <div>
-                    {state.type === "LOADING" && <Preloader />}
+                    {state.type === "LOADING" && <Preloader type="ring" />}
                     {state.type === "WAITING_FOR_NETWORK" && (
                         <RequiresOnline>
-                            <Preloader />
+                            <Preloader type="ring" />
                         </RequiresOnline>
                     )}
                     {state.type === "RENDER" && (
diff --git a/src/pages/channels/messaging/MessageRenderer.tsx b/src/pages/channels/messaging/MessageRenderer.tsx
index ab53edf78933a4c86164053f82598cca083511b6..2c665827055234fc1277f7da7ba6a2d3be3022ad 100644
--- a/src/pages/channels/messaging/MessageRenderer.tsx
+++ b/src/pages/channels/messaging/MessageRenderer.tsx
@@ -60,7 +60,7 @@ function MessageRenderer({ id, state, queue }: Props) {
     } else {
         render.push(
             <RequiresOnline>
-                <Preloader />
+                <Preloader type="ring" />
             </RequiresOnline>
         );
     }
@@ -148,7 +148,7 @@ function MessageRenderer({ id, state, queue }: Props) {
     } else {
         render.push(
             <RequiresOnline>
-                <Preloader />
+                <Preloader type="ring" />
             </RequiresOnline>
         );
     }
diff --git a/src/pages/invite/Invite.tsx b/src/pages/invite/Invite.tsx
index cb01eaf116983b8bdbcaa962436a69318a74098e..831895d6536e3d990220b6f6fae234091e975731 100644
--- a/src/pages/invite/Invite.tsx
+++ b/src/pages/invite/Invite.tsx
@@ -34,7 +34,7 @@ export default function Invite() {
             <div className={styles.preloader}>
                 <RequiresOnline>
                     { error ? <Overline type="error" error={error} />
-                        : <Preloader /> }
+                        : <Preloader type="spinner" /> }
                 </RequiresOnline>
             </div>
         )
@@ -52,7 +52,7 @@ export default function Invite() {
                 </div> }
 
             <div className={styles.details}>
-                { processing ? <Preloader /> :
+                { processing ? <Preloader type="ring" /> :
                     <>
                         <h1>{ invite.server_name }</h1>
                         <h2>#{invite.channel_name}</h2>
diff --git a/src/pages/login/forms/CaptchaBlock.tsx b/src/pages/login/forms/CaptchaBlock.tsx
index e55b09800913b9ce501decd20228885fbf8fa4e4..f435f017e8763dbb0f6a1f046cd7459ef538059b 100644
--- a/src/pages/login/forms/CaptchaBlock.tsx
+++ b/src/pages/login/forms/CaptchaBlock.tsx
@@ -20,7 +20,7 @@ export function CaptchaBlock(props: CaptchaProps) {
     }, []);
 
     if (!client.configuration?.features.captcha.enabled)
-        return <Preloader />;
+        return <Preloader type="spinner" />;
 
     return (
         <div>
diff --git a/src/pages/login/forms/Form.tsx b/src/pages/login/forms/Form.tsx
index c3709b58a739bf176e82e144979bf95b325419ac..5d8911b38e27f06a9fb2f9b86924d933cf0bdd2d 100644
--- a/src/pages/login/forms/Form.tsx
+++ b/src/pages/login/forms/Form.tsx
@@ -138,7 +138,7 @@ export function Form({ page, callback }: Props) {
     }
 
     if (captcha) return <CaptchaBlock {...captcha} />;
-    if (loading) return <Preloader />;
+    if (loading) return <Preloader type="spinner" />;
 
     return (
         <div className={styles.form}>
diff --git a/src/pages/settings/panes/Sessions.tsx b/src/pages/settings/panes/Sessions.tsx
index dff80268156353b8a189191eba7571b51d069a7c..e0501d7f7f6daeaba0483e482fd0f02dc8a04417 100644
--- a/src/pages/settings/panes/Sessions.tsx
+++ b/src/pages/settings/panes/Sessions.tsx
@@ -55,7 +55,7 @@ export function Sessions() {
     if (typeof sessions === "undefined") {
         return (
             <div className={styles.loader}>
-                <Preloader />
+                <Preloader type="ring" />
             </div>
         );
     }
diff --git a/src/pages/settings/server/Invites.tsx b/src/pages/settings/server/Invites.tsx
index 42144a96ffb5420627d8375a68704bccdb5244f8..21e033709fc17ae2204ffe46b9be82e395742745 100644
--- a/src/pages/settings/server/Invites.tsx
+++ b/src/pages/settings/server/Invites.tsx
@@ -27,7 +27,7 @@ export function Invites({ server }: Props) {
 
     return (
         <div className={styles.invites}>
-            { typeof invites === 'undefined' && <Preloader /> }
+            { typeof invites === 'undefined' && <Preloader type="ring" /> }
             {
                 invites?.map(
                     invite => {