diff --git a/web/components/layouts/Main/Main.module.scss b/web/components/layouts/Main/Main.module.scss
index 43111fb4c..4a0825d57 100644
--- a/web/components/layouts/Main/Main.module.scss
+++ b/web/components/layouts/Main/Main.module.scss
@@ -2,37 +2,15 @@
 
 .layout {
   // this margin is for fixed header
-  margin-top: var(--header-height);
+  padding-top: var(--header-height);
   background-color: var(--theme-color-main-background);
-  @include screen(tablet) {
-    position: absolute;
-    top: 0;
-    left: 0;
-    bottom: 0;
-    right: 0;
-    // this one is for fixed footer
-    margin-bottom: 30px;
-  }
+	min-height: 100vh;
+	position: relative;
 
-  @include screen(mobile) {
-    margin-bottom: 0px;
-
-    footer {
-      display: none;
-    }
-  }
-}
-
-.fadeIn {
-  animation: fadein 0.5s;
-}
-
-@keyframes fadein {
-  from {
-    opacity: 0;
-  }
-
-  to {
-    opacity: 1;
-  }
+	// add some spacing between the last row of content and the footer
+	:global(.ant-row) {
+		&:last-of-type {
+			margin-bottom: 5em;
+		}
+	}
 }
diff --git a/web/components/layouts/Main/Main.tsx b/web/components/layouts/Main/Main.tsx
index 905d941bb..20d2fb079 100644
--- a/web/components/layouts/Main/Main.tsx
+++ b/web/components/layouts/Main/Main.tsx
@@ -3,7 +3,7 @@
 /* eslint-disable react/no-unescaped-entities */
 import { useRecoilValue } from 'recoil';
 import Head from 'next/head';
-import { FC, useEffect, useRef, useState } from 'react';
+import { FC, useEffect, useRef } from 'react';
 import { Layout } from 'antd';
 import dynamic from 'next/dynamic';
 import Script from 'next/script';
@@ -32,6 +32,7 @@ import { PushNotificationServiceWorker } from '../../workers/PushNotificationSer
 import { AppStateOptions } from '../../stores/application-state';
 import { Noscript } from '../../ui/Noscript/Noscript';
 import { ServerStatus } from '../../../interfaces/server-status.model';
+import { DYNAMIC_PADDING_VALUE } from '../../../utils/constants';
 
 // Lazy loaded components
 
@@ -46,7 +47,6 @@ const FatalErrorStateModal = dynamic(
 );
 
 export const Main: FC = () => {
-  const [displayFooter, setDisplayFooter] = useState(false);
   const clientConfig = useRecoilValue<ClientConfig>(clientConfigStateAtom);
   const clientStatus = useRecoilValue<ServerStatus>(serverStatusState);
   const { name } = clientConfig;
@@ -58,42 +58,16 @@ export const Main: FC = () => {
   const layoutRef = useRef<HTMLDivElement>(null);
   const { chatDisabled } = clientConfig;
   const { videoAvailable } = appState;
-  const { online, streamTitle, versionNumber: version } = clientStatus;
+  const { online, streamTitle } = clientStatus;
 
   // accounts for sidebar width when online in desktop
   const showChat = online && !chatDisabled && isChatVisible;
-  const dynamicFooterPadding = showChat && !isMobile ? '340px' : '20px';
+  const dynamicFooterPadding = showChat && !isMobile ? DYNAMIC_PADDING_VALUE : '';
 
   useEffect(() => {
     setupNoLinkReferrer(layoutRef.current);
   }, []);
 
-  const handleScroll = () => {
-    const documentHeight = document.body.scrollHeight;
-    const currentScroll = window.scrollY + window.innerHeight;
-
-    // When the user is [modifier]px from the bottom, fire the event.
-    const modifier = 10;
-    if (currentScroll + modifier > documentHeight) {
-      if (!displayFooter) {
-        setDisplayFooter(true);
-      }
-    } else {
-      // eslint-disable-next-line no-lonely-if
-      if (displayFooter) {
-        setDisplayFooter(false);
-      }
-    }
-  };
-
-  useEffect(() => {
-    window.addEventListener('scroll', handleScroll);
-
-    return () => {
-      window.removeEventListener('scroll', handleScroll);
-    };
-  }, [displayFooter]);
-
   const isProduction = process.env.NODE_ENV === 'production';
   const headerText = online ? streamTitle || name : name;
 
@@ -196,12 +170,8 @@ export const Main: FC = () => {
         {fatalError && (
           <FatalErrorStateModal title={fatalError.title} message={fatalError.message} />
         )}
-        <div
-          style={displayFooter ? { display: 'flex' } : { display: 'none' }}
-          className={styles.fadeIn}
-        >
-          <Footer version={version} dynamicPadding={dynamicFooterPadding} />
-        </div>
+
+        {(!isMobile || !online) && <Footer dynamicPaddingValue={dynamicFooterPadding} />}
       </Layout>
       <Noscript />
     </>
diff --git a/web/components/ui/Content/Content.module.scss b/web/components/ui/Content/Content.module.scss
index 326b51360..d4f1645df 100644
--- a/web/components/ui/Content/Content.module.scss
+++ b/web/components/ui/Content/Content.module.scss
@@ -4,22 +4,23 @@
   padding: var(--content-padding);
 }
 
-.lowerSectionMobile {
+.lowerSectionMobileTabbed {
   display: flex;
   flex-direction: column;
   flex-grow: 1;
   flex-shrink: 0;
-  position: absolute;
+  position: relative;
   bottom: 0;
   width: 100%;
 
-  @include screen(tablet) {
+	@include screen(tablet) {
+		top: 0;
     position: relative;
-  }
 
-  @include screen(mobile) {
-    //sets the position of tabbed content for online mode
-    top: 280px;
+		&.online {
+			position: absolute;
+			top: calc(var(--player-container-height) + var(--status-bar-height) + var(--header-height));
+		}
   }
 
   :global(.ant-tabs-nav) {
@@ -29,15 +30,7 @@
   }
 }
 
-.online {
-  @include screen(tablet) {
-    //sets the position of tabbed content for online mode
-    position: absolute;
-    top: 430px;
-  }
-}
-
-.mobileNoTabs {
+.lowerSectionMobileNoTabs {
   padding-top: 20px;
 }
 
diff --git a/web/components/ui/Content/MobileContent.tsx b/web/components/ui/Content/MobileContent.tsx
index 487ab27aa..81c7b4bc3 100644
--- a/web/components/ui/Content/MobileContent.tsx
+++ b/web/components/ui/Content/MobileContent.tsx
@@ -137,10 +137,13 @@ export const MobileContent: FC<MobileContentProps> = ({
         <ComponentErrorFallback error={error} resetErrorBoundary={resetErrorBoundary} />
       )}
     >
-      <div className={classNames([styles.lowerSectionMobile, online && styles.online])}>
-        {items.length > 1 && <Tabs defaultActiveKey="0" items={items} />}
-      </div>
-      <div className={styles.mobileNoTabs}>{items.length <= 1 && aboutTabContent}</div>
+      {items.length > 1 ? (
+        <div className={classNames([styles.lowerSectionMobileTabbed, online && styles.online])}>
+          <Tabs defaultActiveKey="0" items={items} />
+        </div>
+      ) : (
+        <div className={styles.lowerSectionMobileNoTabs}>{aboutTabContent}</div>
+      )}
     </ErrorBoundary>
   );
 };
diff --git a/web/components/ui/Footer/Footer.module.scss b/web/components/ui/Footer/Footer.module.scss
index c0a11fd0a..bfa960c31 100644
--- a/web/components/ui/Footer/Footer.module.scss
+++ b/web/components/ui/Footer/Footer.module.scss
@@ -1,33 +1,28 @@
 @import '../../../styles/mixins.scss';
 
 .footer {
+
+	position: absolute;
+	bottom: 0;
+
   display: flex;
   align-items: center;
   flex-wrap: wrap;
-  height: var(--footer-height);
   justify-content: space-between;
   flex-direction: row;
   background-color: var(--theme-color-background-header);
   color: var(--theme-color-components-text-on-dark);
   font-family: var(--theme-text-body-font-family);
 
-  padding: 0.6rem 1rem;
+  padding: 0.6rem var(--footer-padding-x);
   font-size: 0.75rem;
   font-weight: 400;
   border-top: 1px solid rgba(214, 211, 211, 0.5);
   width: 100%;
-      position: fixed;
-        bottom: 0;
+
 
   @include screen(tablet) {
     font-size: 10px;
-    position: fixed;
-    bottom: 0;
-  }
-
-  @include screen(mobile) {
-    position: fixed;
-    bottom: 0;
   }
 
   a {
diff --git a/web/components/ui/Footer/Footer.stories.tsx b/web/components/ui/Footer/Footer.stories.tsx
index 69ee6cd6b..40eb48975 100644
--- a/web/components/ui/Footer/Footer.stories.tsx
+++ b/web/components/ui/Footer/Footer.stories.tsx
@@ -1,5 +1,6 @@
 import React from 'react';
 import { ComponentStory, ComponentMeta } from '@storybook/react';
+import { RecoilRoot } from 'recoil';
 import { Footer } from './Footer';
 
 export default {
@@ -8,7 +9,11 @@ export default {
   parameters: {},
 } as ComponentMeta<typeof Footer>;
 
-const Template: ComponentStory<typeof Footer> = args => <Footer {...args} />;
+const Template: ComponentStory<typeof Footer> = args => (
+  <RecoilRoot>
+    <Footer {...args} />
+  </RecoilRoot>
+);
 
 // eslint-disable-next-line @typescript-eslint/no-unused-vars
 export const Example = Template.bind({});
diff --git a/web/components/ui/Footer/Footer.tsx b/web/components/ui/Footer/Footer.tsx
index b819d7699..eb95f025c 100644
--- a/web/components/ui/Footer/Footer.tsx
+++ b/web/components/ui/Footer/Footer.tsx
@@ -1,27 +1,36 @@
 import { FC } from 'react';
+import { useRecoilValue } from 'recoil';
 import styles from './Footer.module.scss';
+import { ServerStatus } from '../../../interfaces/server-status.model';
+import { serverStatusState } from '../../stores/ClientConfigStore';
 
 export type FooterProps = {
-  version: string;
-  dynamicPadding: string;
+  dynamicPaddingValue?: string;
 };
 
-export const Footer: FC<FooterProps> = ({ version, dynamicPadding }) => (
-  <footer className={styles.footer} id="footer" style={{ paddingRight: dynamicPadding }}>
-    <span>
-      Powered by <a href="https://owncast.online">Owncast v{version}</a>
-    </span>
-    <span className={styles.links}>
-      <a href="https://owncast.online/docs" target="_blank" rel="noreferrer">
-        Documentation
-      </a>
-      <a href="https://owncast.online/help" target="_blank" rel="noreferrer">
-        Contribute
-      </a>
-      <a href="https://github.com/owncast/owncast" target="_blank" rel="noreferrer">
-        Source
-      </a>
-    </span>
-  </footer>
-);
+export const Footer: FC<FooterProps> = ({ dynamicPaddingValue }) => {
+  const clientStatus = useRecoilValue<ServerStatus>(serverStatusState);
+  const { versionNumber } = clientStatus;
+  const dynamicPaddingStyle = dynamicPaddingValue
+    ? { paddingRight: `calc(${dynamicPaddingValue} + var(--footer-padding-x)` }
+    : null;
+  return (
+    <footer className={styles.footer} id="footer" style={dynamicPaddingStyle}>
+      <span>
+        Powered by <a href="https://owncast.online">Owncast v{versionNumber}</a>
+      </span>
+      <span className={styles.links}>
+        <a href="https://owncast.online/docs" target="_blank" rel="noreferrer">
+          Documentation
+        </a>
+        <a href="https://owncast.online/help" target="_blank" rel="noreferrer">
+          Contribute
+        </a>
+        <a href="https://github.com/owncast/owncast" target="_blank" rel="noreferrer">
+          Source
+        </a>
+      </span>
+    </footer>
+  );
+};
 export default Footer;
diff --git a/web/components/ui/Statusbar/Statusbar.module.scss b/web/components/ui/Statusbar/Statusbar.module.scss
index abdc6ea8b..22f54a1db 100644
--- a/web/components/ui/Statusbar/Statusbar.module.scss
+++ b/web/components/ui/Statusbar/Statusbar.module.scss
@@ -2,7 +2,7 @@
   display: flex;
   align-items: center;
   justify-content: space-between;
-  height: 2rem;
+  height: var(--status-bar-height);
   width: 100%;
   padding: var(--content-padding);
   color: var(--theme-color-components-video-status-bar-foreground);
diff --git a/web/components/video/OwncastPlayer/OwncastPlayer.module.scss b/web/components/video/OwncastPlayer/OwncastPlayer.module.scss
index a49218157..1f507d41f 100644
--- a/web/components/video/OwncastPlayer/OwncastPlayer.module.scss
+++ b/web/components/video/OwncastPlayer/OwncastPlayer.module.scss
@@ -4,12 +4,12 @@
   display: grid;
   width: 100%;
   justify-items: center;
-  height: 75vh;
+  height: var(--player-container-height);
   aspect-ratio: 16 / 9;
 
   @media (max-width: 1200px) {
     height: 100%;
-    max-height: 75vh;
+    max-height: var(--player-container-height);
   }
 
   @include screen(desktop) {
@@ -19,14 +19,8 @@
 
   //set height of player for tablet
   @include screen(tablet) {
-    height: 400px;
-    max-height: 400px;
-  }
-
-  //set height of player for mobile
-  @include screen(mobile) {
-    height: 250px;
-    max-height: 250px;
+    height: var(--player-container-height);
+    max-height: var(--player-container-height);
   }
 
   .player,
diff --git a/web/styles/globals.scss b/web/styles/globals.scss
index 68857174f..4e8b1c814 100644
--- a/web/styles/globals.scss
+++ b/web/styles/globals.scss
@@ -10,7 +10,6 @@
   --content-padding: 0.95rem;
   --module-spacing: 12px; // margin size between lines of stuff, if needed
   --header-height: 70px; // needed for making main content scrollable;
-  --footer-height: 2.5rem; // needed for making main content scrollable;
   --content-height: calc(100vh - var(--header-height));
   --replacement-bar-height: 46px; // needed for making main content scrollable on mobile;
 
@@ -19,10 +18,19 @@
   --chat-notification-icon-padding: 6px;
   --chat-message-padding: 10px;
   --chat-text-highlight-border-radius: 3px;
+	--chat-col-width: 320px;
+
+	--player-container-height: 75vh;
+	--status-bar-height: 2rem;
+	--footer-padding-x: 1rem;
 
   @include screen(tablet) {
     --header-height: 3.85rem;
+		--player-container-height: 400px;
   }
+	@include screen(mobile) {
+		--player-container-height: 250px;
+	}
 }
 
 ::selection {
diff --git a/web/utils/constants.js b/web/utils/constants.js
index 451552d91..b2642ffcd 100644
--- a/web/utils/constants.js
+++ b/web/utils/constants.js
@@ -74,3 +74,5 @@ export const HAS_DISPLAYED_NOTIFICATION_MODAL_KEY = 'HAS_DISPLAYED_NOTIFICATION_
 export const USER_VISIT_COUNT_KEY = 'USER_VISIT_COUNT';
 export const USER_DISMISSED_ANNOYING_NOTIFICATION_POPUP_KEY =
   'USER_DISMISSED_ANNOYING_NOTIFICATION_POPUP_KEY';
+
+export const DYNAMIC_PADDING_VALUE = '320px';