diff --git a/apps/jetstream-e2e/playwright.config.ts b/apps/jetstream-e2e/playwright.config.ts
index 8cdb3a743..55ed727f2 100644
--- a/apps/jetstream-e2e/playwright.config.ts
+++ b/apps/jetstream-e2e/playwright.config.ts
@@ -63,15 +63,5 @@ export default defineConfig({
       dependencies: ['setup'],
       // teardown: 'teardown',
     },
-
-    // {
-    //   name: 'firefox',
-    //   use: { ...devices['Desktop Firefox'] },
-    // },
-
-    // {
-    //   name: 'webkit',
-    //   use: { ...devices['Desktop Safari'] },
-    // },
   ],
 });
diff --git a/apps/jetstream-web-extension/src/assets/icons/jetstream-icon-inverse-128.png b/apps/jetstream-web-extension/src/assets/icons/jetstream-icon-inverse-128.png
new file mode 100644
index 000000000..bceb44b70
Binary files /dev/null and b/apps/jetstream-web-extension/src/assets/icons/jetstream-icon-inverse-128.png differ
diff --git a/apps/jetstream-web-extension/src/assets/icons/jetstream-icon-inverse-16.png b/apps/jetstream-web-extension/src/assets/icons/jetstream-icon-inverse-16.png
new file mode 100644
index 000000000..d9c223787
Binary files /dev/null and b/apps/jetstream-web-extension/src/assets/icons/jetstream-icon-inverse-16.png differ
diff --git a/apps/jetstream-web-extension/src/assets/icons/jetstream-icon-inverse-24.png b/apps/jetstream-web-extension/src/assets/icons/jetstream-icon-inverse-24.png
new file mode 100644
index 000000000..3d3d8b5c0
Binary files /dev/null and b/apps/jetstream-web-extension/src/assets/icons/jetstream-icon-inverse-24.png differ
diff --git a/apps/jetstream-web-extension/src/assets/icons/jetstream-icon-inverse-32.png b/apps/jetstream-web-extension/src/assets/icons/jetstream-icon-inverse-32.png
new file mode 100644
index 000000000..ef1b84d89
Binary files /dev/null and b/apps/jetstream-web-extension/src/assets/icons/jetstream-icon-inverse-32.png differ
diff --git a/apps/jetstream-web-extension/src/assets/icons/jetstream-icon-inverse-48.png b/apps/jetstream-web-extension/src/assets/icons/jetstream-icon-inverse-48.png
new file mode 100644
index 000000000..0a530e1a2
Binary files /dev/null and b/apps/jetstream-web-extension/src/assets/icons/jetstream-icon-inverse-48.png differ
diff --git a/apps/jetstream-web-extension/src/components/SfdcPageButton.tsx b/apps/jetstream-web-extension/src/components/SfdcPageButton.tsx
index f12cbde58..31a8bb48f 100644
--- a/apps/jetstream-web-extension/src/components/SfdcPageButton.tsx
+++ b/apps/jetstream-web-extension/src/components/SfdcPageButton.tsx
@@ -126,7 +126,7 @@ const ButtonLinkCss = css`
 
 export function SfdcPageButton() {
   const options = useRecoilValue(chromeStorageOptions);
-  const { authTokens } = useRecoilValue(chromeSyncStorage);
+  const { authTokens, buttonPosition } = useRecoilValue(chromeSyncStorage);
   const [isOnSalesforcePage] = useState(
     () => !!document.querySelector('body.sfdcBody, body.ApexCSIPage, #auraLoadingBox') || location.host.endsWith('visualforce.com')
   );
@@ -202,33 +202,33 @@ export function SfdcPageButton() {
       <button
         data-testid="jetstream-ext-page-button"
         css={css`
-        z-index: 1000;
-        display: block;
-        position: fixed;
-        vertical-align: middle;
-        pointer: cursor;
-        top: 210px;
-        right: ${isOpen ? '0px;' : '-5px;'};
-        opacity: ${isOpen ? '1;' : '0.25;'};
-        width: 25px;
-        transition: transform 0.3s ease;
-        transform: ${isOpen ? 'scale(1.5);' : 'scale(1);'}
-        transform-origin: top right;
+          z-index: 1000;
+          display: ${isOpen ? 'none' : 'block'};
+          position: fixed;
+          vertical-align: middle;
+          pointer: cursor;
+          top: clamp(1px, ${buttonPosition.position}px, 100vh);
+          ${buttonPosition.location}: ${isOpen ? '0px' : '-5px'};
+          opacity: ${isOpen ? '1' : `${buttonPosition.opacity}`};
+          width: ${buttonPosition.inactiveSize}px;
+          transition: transform 0.3s ease;
+          transform: ${isOpen ? `scale(${buttonPosition.activeScale})` : 'scale(1)'};
+          transform-origin: top ${buttonPosition.location};
 
-        background: none;
-        border: none;
-        padding: 0;
-        margin: 0;
-        cursor: pointer;
-        outline: none;
-        text-align: center;
+          background: none;
+          border: none;
+          padding: 0;
+          margin: 0;
+          cursor: pointer;
+          outline: none;
+          text-align: center;
 
-        &:hover {
-          opacity: 1;
-          right: 0px;
-          transform: scale(1.5);
-        }
-      `}
+          &:hover {
+            opacity: 1;
+            ${buttonPosition.location}: 0px;
+            transform: scale(${buttonPosition.activeScale});
+          }
+        `}
         onClick={() => setIsOpen(true)}
       >
         <JetstreamIcon />
@@ -239,8 +239,8 @@ export function SfdcPageButton() {
             z-index: 1000;
             display: block;
             position: fixed;
-            top: 160px;
-            right: 0;
+            top: clamp(1px, ${buttonPosition.position - 50}px, calc(100vh - 500px));
+            ${buttonPosition.location}: 0;
             width: 250px;
             border-radius: var(--lwc-borderRadiusMedium, 0.25rem);
             min-height: 2rem;
diff --git a/apps/jetstream-web-extension/src/core/AppInitializer.tsx b/apps/jetstream-web-extension/src/core/AppInitializer.tsx
index ded19ce68..702393c66 100644
--- a/apps/jetstream-web-extension/src/core/AppInitializer.tsx
+++ b/apps/jetstream-web-extension/src/core/AppInitializer.tsx
@@ -9,8 +9,10 @@ import localforage from 'localforage';
 import React, { FunctionComponent, useEffect, useState } from 'react';
 import { useLocation } from 'react-router-dom';
 import { useRecoilValue, useSetRecoilState } from 'recoil';
+import { chromeSyncStorage } from '../utils/extension.store';
 import { sendMessage } from '../utils/web-extension.utils';
 import { GlobalExtensionError } from './GlobalExtensionError';
+import { GlobalExtensionLoggedOut } from './GlobalExtensionLoggedOut';
 
 const args = new URLSearchParams(location.search.slice(1));
 const salesforceHost = args.get('host');
@@ -29,6 +31,8 @@ export const AppInitializer: FunctionComponent<AppInitializerProps> = ({ onUserP
   const location = useLocation();
   const userProfile = useRecoilValue<UserProfileUi>(fromAppState.userProfileState);
 
+  const { authTokens } = useRecoilValue(chromeSyncStorage);
+
   const setSelectedOrgId = useSetRecoilState(fromAppState.selectedOrgIdState);
   const setSalesforceOrgs = useSetRecoilState(fromAppState.salesforceOrgsState);
   const selectedOrg = useRecoilValue(fromAppState.selectedOrgState);
@@ -77,6 +81,10 @@ export const AppInitializer: FunctionComponent<AppInitializerProps> = ({ onUserP
     return <GlobalExtensionError message={fatalError} />;
   }
 
+  if (!authTokens?.loggedIn) {
+    return <GlobalExtensionLoggedOut />;
+  }
+
   if (!salesforceHost || !selectedOrg?.uniqueId) {
     return <AppLoading />;
   }
diff --git a/apps/jetstream-web-extension/src/core/GlobalExtensionLoggedOut.tsx b/apps/jetstream-web-extension/src/core/GlobalExtensionLoggedOut.tsx
new file mode 100644
index 000000000..057cb21d0
--- /dev/null
+++ b/apps/jetstream-web-extension/src/core/GlobalExtensionLoggedOut.tsx
@@ -0,0 +1,37 @@
+import { FeedbackLink, Grid } from '@jetstream/ui';
+import { environment } from '../environments/environment';
+
+export const GlobalExtensionLoggedOut = () => {
+  return (
+    <div className="slds-card slds-box">
+      <p>This page is only accessible when you are logged in to the Chrome extension. Login to continue.</p>
+      <a
+        href={`${environment.serverUrl}/web-extension/init`}
+        target="_blank"
+        className="slds-button slds-button_brand slds-m-top_small"
+        rel="noreferrer"
+      >
+        Sign In
+      </a>
+      <hr className="slds-m-vertical_medium" />
+      <Grid vertical>
+        <div>
+          <ol className="slds-list_ordered">
+            <li>
+              Bug reports and feature requests - <FeedbackLink type="GH_ISSUE" />
+            </li>
+            <li className="slds-m-top_x-small">
+              <FeedbackLink type="GH_DISCUSSION" />
+            </li>
+            <li className="slds-m-top_x-small">
+              Ask a question in the <strong>#vendors-jetstream</strong> Discord channel <FeedbackLink type="DISCORD" />
+            </li>
+            <li className="slds-m-top_x-small">
+              You can always email us at <FeedbackLink type="EMAIL" />
+            </li>
+          </ol>
+        </div>
+      </Grid>
+    </div>
+  );
+};
diff --git a/apps/jetstream-web-extension/src/pages/app/app.html b/apps/jetstream-web-extension/src/pages/app/app.html
index cc927fa71..ff03e8bd9 100644
--- a/apps/jetstream-web-extension/src/pages/app/app.html
+++ b/apps/jetstream-web-extension/src/pages/app/app.html
@@ -3,6 +3,7 @@
   <head>
     <meta charset="UTF-8" />
     <meta name="viewport" content="width=device-width, initial-scale=1" />
+    <link rel="icon" href="assets/icons/jetstream-icon-inverse-16.png" type="image/png" />
     <title>Jetstream</title>
   </head>
 
diff --git a/apps/jetstream-web-extension/src/pages/popup/Popup.tsx b/apps/jetstream-web-extension/src/pages/popup/Popup.tsx
index 228c89626..9d1d23a43 100644
--- a/apps/jetstream-web-extension/src/pages/popup/Popup.tsx
+++ b/apps/jetstream-web-extension/src/pages/popup/Popup.tsx
@@ -1,11 +1,14 @@
-import { useNonInitialEffect } from '@jetstream/shared/ui-utils';
-import { CheckboxToggle, FeedbackLink, ScopedNotification } from '@jetstream/ui';
-import { useEffect, useState } from 'react';
+import { css } from '@emotion/react';
+import { useDebounce, useNonInitialEffect } from '@jetstream/shared/ui-utils';
+import { CheckboxToggle, FeedbackLink, RadioButton, RadioGroup, ScopedNotification, Slider } from '@jetstream/ui';
+import { useEffect, useMemo, useState } from 'react';
 import { useRecoilValue } from 'recoil';
+import JetstreamIcon from '../../components/icons/JetstreamIcon';
 import JetstreamLogo from '../../components/icons/JetstreamLogo';
 import { AppWrapperNotJetstreamOwnedPage } from '../../core/AppWrapperNotJetstreamOwnedPage';
 import { environment } from '../../environments/environment';
 import { chromeStorageOptions, chromeSyncStorage } from '../../utils/extension.store';
+import { ButtonPosition, DEFAULT_BUTTON_POSITION } from '../../utils/extension.types';
 import { initAndRenderReact, sendMessage } from '../../utils/web-extension.utils';
 
 initAndRenderReact(
@@ -18,10 +21,37 @@ export function Component() {
   const options = useRecoilValue(chromeStorageOptions);
   const [enabled, setEnabled] = useState(options.enabled);
   const [authError, setAuthError] = useState<string | null>(null);
-  const { authTokens } = useRecoilValue(chromeSyncStorage);
+  const { authTokens, buttonPosition: _buttonPosition } = useRecoilValue(chromeSyncStorage);
+
+  const [buttonOptionsVisible, setButtonOptionsVisible] = useState(false);
+
+  const [buttonLocation, setButtonLocation] = useState(_buttonPosition.location);
+  const [buttonPosition, setButtonPosition] = useState(_buttonPosition.position);
+  const [buttonOpacity, setButtonOpacity] = useState(_buttonPosition.opacity);
+  const [buttonInactiveSize, setButtonInactiveSize] = useState(_buttonPosition.inactiveSize);
+  const [buttonActiveScale, setButtonActiveScale] = useState(_buttonPosition.activeScale);
+
+  const currentButtonPosition = useMemo(
+    (): ButtonPosition => ({
+      location: buttonLocation,
+      position: buttonPosition,
+      opacity: buttonOpacity,
+      inactiveSize: buttonInactiveSize,
+      activeScale: buttonActiveScale,
+    }),
+    [buttonActiveScale, buttonInactiveSize, buttonLocation, buttonOpacity, buttonPosition]
+  );
+
+  const currentButtonPositionDebounced = useDebounce(currentButtonPosition, 500);
 
   const loggedIn = !!authTokens?.loggedIn;
 
+  useNonInitialEffect(() => {
+    chrome.storage.sync.set({ buttonPosition: currentButtonPositionDebounced }).catch((ex) => {
+      console.warn('Error setting button position', ex);
+    });
+  }, [currentButtonPositionDebounced]);
+
   useEffect(() => {
     sendMessage({ message: 'VERIFY_AUTH' }).catch((err) => {
       setAuthError('There was a problem verifying your authentication. Please log in again.');
@@ -44,6 +74,15 @@ export function Component() {
       });
   }
 
+  function handleResetButtonOptions() {
+    setButtonLocation(DEFAULT_BUTTON_POSITION.location);
+    setButtonPosition(DEFAULT_BUTTON_POSITION.position);
+    setButtonOpacity(DEFAULT_BUTTON_POSITION.opacity);
+    setButtonInactiveSize(DEFAULT_BUTTON_POSITION.inactiveSize);
+    setButtonActiveScale(DEFAULT_BUTTON_POSITION.activeScale);
+    setButtonOptionsVisible(false);
+  }
+
   return (
     <>
       <header className="slds-m-bottom_medium">
@@ -71,6 +110,13 @@ export function Component() {
             />
             <hr className="slds-m-vertical_small" />
             <p>Visit any Salesforce page to see the floating Jetstream button icon on the right side of the page.</p>
+            <div
+              css={css`
+                width: 25px;
+              `}
+            >
+              <JetstreamIcon />
+            </div>
             <hr className="slds-m-vertical_small" />
             <p className="slds-m-bottom_x-small">Feedback or Suggestions?</p>
             <div>
@@ -79,6 +125,78 @@ export function Component() {
             <div>
               <FeedbackLink type="EMAIL" label="Send us an email" />
             </div>
+            <hr className="slds-m-vertical_small" />
+            <p>Salesforce Button Location</p>
+            {!buttonOptionsVisible && (
+              <button className="slds-button slds-m-top_x-small" onClick={() => setButtonOptionsVisible(true)}>
+                Show Configuration Options
+              </button>
+            )}
+            {buttonOptionsVisible && (
+              <>
+                <button className="slds-button slds-m-top_x-small slds-m-bottom_small" onClick={() => handleResetButtonOptions()}>
+                  Reset to Default
+                </button>
+                <RadioGroup label="Name Type" isButtonGroup className="slds-m-bottom_small">
+                  <RadioButton
+                    id="sfdc-button-slider-location-left"
+                    name="sfdc-button-slider-location"
+                    label="Left"
+                    value="left"
+                    checked={buttonLocation === 'left'}
+                    onChange={(value) => setButtonLocation(value as 'left')}
+                  />
+                  <RadioButton
+                    id="sfdc-button-slider-location-rigt"
+                    name="sfdc-button-slider-location"
+                    label="Right"
+                    value="right"
+                    checked={buttonLocation === 'right'}
+                    onChange={(value) => setButtonLocation(value as 'right')}
+                  />
+                </RadioGroup>
+                <Slider
+                  id="sfdc-button-slider-position"
+                  value={`${buttonPosition}`}
+                  label="Vertical Position"
+                  labelHelp="The vertical position of the Jetstream icon on the page."
+                  min={1}
+                  max={window.screen.height - 50 || 1000}
+                  step={10}
+                  onChange={(value) => setButtonPosition(parseInt(value, 10))}
+                />
+                <Slider
+                  id="sfdc-button-slider-opacity"
+                  value={`${buttonOpacity}`}
+                  label="Jetstream Icon Opacity"
+                  labelHelp="Opacity of the Jetstream icon when it is not being hovered over."
+                  min={0.1}
+                  max={1}
+                  step={0.05}
+                  onChange={(value) => setButtonOpacity(Number(value))}
+                />
+                <Slider
+                  id="sfdc-button-slider-inactive-size"
+                  value={`${buttonInactiveSize}`}
+                  label="Jetstream Icon Size"
+                  labelHelp="Size of the Jetstream icon when it is not being hovered over."
+                  min={20}
+                  max={100}
+                  step={5}
+                  onChange={(value) => setButtonInactiveSize(Number(value))}
+                />
+                <Slider
+                  id="sfdc-button-slider-active-scale"
+                  value={`${buttonActiveScale}`}
+                  label="Button Hover Scale"
+                  labelHelp="The scale of the button when you hover over it. 1 is the same size as the non-hovered button."
+                  min={1}
+                  max={5}
+                  step={0.1}
+                  onChange={(value) => setButtonActiveScale(Number(value))}
+                />
+              </>
+            )}
           </>
         )}
         {(!loggedIn || !authTokens) && (
diff --git a/apps/jetstream-web-extension/src/pages/popup/popup.html b/apps/jetstream-web-extension/src/pages/popup/popup.html
index 774ff8f42..7b92be3bf 100644
--- a/apps/jetstream-web-extension/src/pages/popup/popup.html
+++ b/apps/jetstream-web-extension/src/pages/popup/popup.html
@@ -7,7 +7,7 @@
     <style>
       body {
         width: 350px;
-        height: 400px;
+        min-height: 400px;
         background-color: white !important;
         padding: 15px;
       }
diff --git a/apps/jetstream-web-extension/src/utils/extension.store.ts b/apps/jetstream-web-extension/src/utils/extension.store.ts
index 75db85b07..0f76e59eb 100644
--- a/apps/jetstream-web-extension/src/utils/extension.store.ts
+++ b/apps/jetstream-web-extension/src/utils/extension.store.ts
@@ -1,6 +1,6 @@
 import { atom, selector } from 'recoil';
 import { setRecoil } from 'recoil-nexus';
-import { ChromeStorageState } from './extension.types';
+import { ChromeStorageState, DEFAULT_BUTTON_POSITION } from './extension.types';
 
 chrome.storage.onChanged.addListener((changes, namespace) => {
   if (namespace === 'local' || namespace === 'sync') {
@@ -23,6 +23,7 @@ chrome.storage.onChanged.addListener((changes, namespace) => {
 
       newState.sync.authTokens = newState.sync.authTokens ?? null;
       newState.sync.extIdentifier = newState.sync.extIdentifier ?? null;
+      newState.sync.buttonPosition = newState.sync.buttonPosition ?? DEFAULT_BUTTON_POSITION;
 
       return newState;
     });
@@ -32,7 +33,7 @@ chrome.storage.onChanged.addListener((changes, namespace) => {
 async function initAuthState(): Promise<ChromeStorageState> {
   const [local, sync] = await Promise.all([
     chrome.storage.local.get(['options', 'connections']),
-    chrome.storage.sync.get(['extIdentifier', 'authTokens']),
+    chrome.storage.sync.get(['extIdentifier', 'authTokens', 'buttonPosition']),
   ]);
   return {
     local: {
@@ -46,6 +47,10 @@ async function initAuthState(): Promise<ChromeStorageState> {
       ...(sync as ChromeStorageState['sync']),
       authTokens: (sync as ChromeStorageState['sync'])?.authTokens ?? null,
       extIdentifier: (sync as ChromeStorageState['sync'])?.extIdentifier ?? null,
+      buttonPosition: {
+        ...DEFAULT_BUTTON_POSITION,
+        ...(sync as ChromeStorageState['sync'])?.buttonPosition,
+      },
     },
   };
 }
diff --git a/apps/jetstream-web-extension/src/utils/extension.types.ts b/apps/jetstream-web-extension/src/utils/extension.types.ts
index 472fb040e..e60c9ca36 100644
--- a/apps/jetstream-web-extension/src/utils/extension.types.ts
+++ b/apps/jetstream-web-extension/src/utils/extension.types.ts
@@ -4,6 +4,22 @@ import { z } from 'zod';
 
 export const AUTH_CHECK_INTERVAL_MIN = 5;
 
+export const DEFAULT_BUTTON_POSITION: ButtonPosition = {
+  location: 'right',
+  position: 210,
+  opacity: 0.25,
+  inactiveSize: 25,
+  activeScale: 1.5,
+};
+
+export interface ButtonPosition {
+  location: 'left' | 'right';
+  position: number;
+  opacity: number;
+  inactiveSize: number;
+  activeScale: number;
+}
+
 export interface JwtPayload {
   userId: string;
   name: string;
@@ -19,6 +35,7 @@ export interface ChromeStorageState {
   sync: {
     extIdentifier: z.infer<typeof ExtensionIdentifier> | null;
     authTokens: z.infer<typeof AuthTokens> | null;
+    buttonPosition: ButtonPosition;
   };
   local: {
     options: {
diff --git a/libs/ui/src/index.ts b/libs/ui/src/index.ts
index 11dd2ac31..1f3e3b53e 100644
--- a/libs/ui/src/index.ts
+++ b/libs/ui/src/index.ts
@@ -63,6 +63,7 @@ export * from './lib/form/radio/RadioGroup';
 export * from './lib/form/readonly-form-element/ReadOnlyFormElement';
 export * from './lib/form/search-input/SearchInput';
 export * from './lib/form/select/Select';
+export * from './lib/form/slider/Slider';
 export * from './lib/form/textarea/Textarea';
 export * from './lib/form/time-picker/TimePicker';
 export * from './lib/google/GoogleSignIn';
diff --git a/libs/ui/src/lib/form/slider/Slider.tsx b/libs/ui/src/lib/form/slider/Slider.tsx
index cd2c480f8..521ed8dc9 100644
--- a/libs/ui/src/lib/form/slider/Slider.tsx
+++ b/libs/ui/src/lib/form/slider/Slider.tsx
@@ -1,3 +1,4 @@
+import { css } from '@emotion/react';
 import { SizeXSmallSmallMediumLarge } from '@jetstream/types';
 import classNames from 'classnames';
 import React, { FunctionComponent, RefObject } from 'react';
@@ -11,8 +12,9 @@ export interface SliderProps {
   size?: SizeXSmallSmallMediumLarge;
   value: string;
   label: string;
-  rangeLabel: string;
+  rangeLabel?: string;
   hideLabel?: boolean;
+  hideRangLabel?: boolean;
   labelHelp?: string | JSX.Element | null;
   helpText?: React.ReactNode | string;
   disabled?: boolean;
@@ -37,6 +39,7 @@ export const Slider: FunctionComponent<SliderProps> = ({
   label,
   rangeLabel,
   hideLabel,
+  hideRangLabel,
   labelHelp,
   helpText,
   hasError = false,
@@ -52,11 +55,14 @@ export const Slider: FunctionComponent<SliderProps> = ({
 }) => {
   // TODO: value state
   const sizeClass = size ? `slds-size_${size}` : undefined;
+  rangeLabel = rangeLabel ?? `${min} - ${max}`;
   return (
     <div className={classNames('slds-form-element', className, { 'slds-has-error': hasError })}>
       <label className="slds-form-element__label" htmlFor={id}>
         <span className={classNames('slds-slider-label__label', { 'sr-only': hideLabel || !label })}>{label}</span>
-        <span className={classNames('slds-slider-label__range', { 'sr-only': hideLabel || !rangeLabel })}>{rangeLabel}</span>
+        <span className={classNames('slds-slider-label__range', { 'sr-only': hideLabel || hideRangLabel || !rangeLabel })}>
+          {rangeLabel}
+        </span>
       </label>
       {labelHelp && !hideLabel && <HelpText id={`${id}-label-help-text`} content={labelHelp} />}
       <div className="slds-form-element__control">
@@ -84,7 +90,13 @@ export const Slider: FunctionComponent<SliderProps> = ({
             step={step}
             onChange={(event) => onChange && onChange(event.target.value)}
           />
-          <span className="slds-slider__value" aria-hidden="true">
+          <span
+            css={css`
+              min-width: 20px;
+            `}
+            className="slds-slider__value"
+            aria-hidden="true"
+          >
             {value}
           </span>
         </div>