Repository: gitify-app/gitify
Pull request #1454 (2024-08-09 10:56:33)

refactor: login pages ui
- Move `Generate a PAT` above `Token` input
- Add size to Button components
- Add Button text (Docs, Login) to OAuth view


Patch:
diff --git a/.vscode/settings.json b/.vscode/settings.json
index 64b9bd6f..e207ee52 100644
--- a/.vscode/settings.json
+++ b/.vscode/settings.json
@@ -1,8 +1,7 @@
 {
   "editor.codeActionsOnSave": {
-    "source.fixAll.eslint": "explicit",
-    "source.organizeImports.biome": "explicit",
-    "quickfix.biome": "explicit"
+    "quickfix.biome": "explicit",
+    "source.organizeImports.biome": "explicit"
   },
   "editor.defaultFormatter": "biomejs.biome",
   "[typescript]": {
diff --git a/package.json b/package.json
index 612d23a9..1b35ae54 100644
--- a/package.json
+++ b/package.json
@@ -107,7 +107,7 @@
     "clsx": "2.1.1",
     "date-fns": "3.6.0",
     "electron-log": "5.1.7",
-    "electron-updater": "6.3.2",
+    "electron-updater": "6.3.3",
     "final-form": "4.20.10",
     "menubar": "9.5.0",
     "nprogress": "0.2.0",
@@ -115,7 +115,7 @@
     "react-dom": "18.3.1",
     "react-final-form": "6.5.9",
     "react-router-dom": "6.26.0",
-    "tailwind-merge": "2.4.0",
+    "tailwind-merge": "2.5.0",
     "ts-loader": "9.5.1",
     "typescript": "5.5.4",
     "update-electron-app": "3.0.0"
@@ -125,7 +125,7 @@
     "@electron/notarize": "2.3.2",
     "@testing-library/react": "16.0.0",
     "@types/jest": "29.5.12",
-    "@types/node": "20.14.14",
+    "@types/node": "20.14.15",
     "@types/nprogress": "0.2.3",
     "@types/react": "18.3.3",
     "@types/react-router-dom": "5.3.3",
@@ -143,7 +143,7 @@
     "resize-observer-polyfill": "1.5.1",
     "rimraf": "6.0.1",
     "style-loader": "4.0.0",
-    "tailwindcss": "3.4.7",
+    "tailwindcss": "3.4.9",
     "ts-jest": "29.2.4",
     "ts-node": "10.9.2",
     "webpack": "5.93.0",
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index 41a7ae21..0d23deb1 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -30,8 +30,8 @@ importers:
         specifier: 5.1.7
         version: 5.1.7
       electron-updater:
-        specifier: 6.3.2
-        version: 6.3.2
+        specifier: 6.3.3
+        version: 6.3.3
       final-form:
         specifier: 4.20.10
         version: 4.20.10
@@ -54,8 +54,8 @@ importers:
         specifier: 6.26.0
         version: 6.26.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
       tailwind-merge:
-        specifier: 2.4.0
-        version: 2.4.0
+        specifier: 2.5.0
+        version: 2.5.0
       ts-loader:
         specifier: 9.5.1
         version: 9.5.1(typescript@5.5.4)(webpack@5.93.0(webpack-cli@5.1.4))
@@ -79,8 +79,8 @@ importers:
         specifier: 29.5.12
         version: 29.5.12
       '@types/node':
-        specifier: 20.14.14
-        version: 20.14.14
+        specifier: 20.14.15
+        version: 20.14.15
       '@types/nprogress':
         specifier: 0.2.3
         version: 0.2.3
@@ -110,7 +110,7 @@ importers:
         version: 9.1.4
       jest:
         specifier: 29.7.0
-        version: 29.7.0(@types/node@20.14.14)(ts-node@10.9.2(@types/node@20.14.14)(typescript@5.5.4))
+        version: 29.7.0(@types/node@20.14.15)(ts-node@10.9.2(@types/node@20.14.15)(typescript@5.5.4))
       jest-environment-jsdom:
         specifier: 29.7.0
         version: 29.7.0
@@ -133,14 +133,14 @@ importers:
         specifier: 4.0.0
         version: 4.0.0(webpack@5.93.0(webpack-cli@5.1.4))
       tailwindcss:
-        specifier: 3.4.7
-        version: 3.4.7(ts-node@10.9.2(@types/node@20.14.14)(typescript@5.5.4))
+        specifier: 3.4.9
+        version: 3.4.9(ts-node@10.9.2(@types/node@20.14.15)(typescript@5.5.4))
       ts-jest:
         specifier: 29.2.4
-        version: 29.2.4(@babel/core@7.24.3)(@jest/transform@29.7.0)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.24.3))(jest@29.7.0(@types/node@20.14.14)(ts-node@10.9.2(@types/node@20.14.14)(typescript@5.5.4)))(typescript@5.5.4)
+        version: 29.2.4(@babel/core@7.24.3)(@jest/transform@29.7.0)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.24.3))(jest@29.7.0(@types/node@20.14.15)(ts-node@10.9.2(@types/node@20.14.15)(typescript@5.5.4)))(typescript@5.5.4)
       ts-node:
         specifier: 10.9.2
-        version: 10.9.2(@types/node@20.14.14)(typescript@5.5.4)
+        version: 10.9.2(@types/node@20.14.15)(typescript@5.5.4)
       webpack:
         specifier: 5.93.0
         version: 5.93.0(webpack-cli@5.1.4)
@@ -685,8 +685,8 @@ packages:
   '@types/ms@0.7.34':
     resolution: {integrity: sha512-nG96G3Wp6acyAgJqGasjODb+acrI7KltPiRxzHPXnP3NgI28bpQDRv53olbqGXbfcgF5aiiHmO3xpwEpS5Ld9g==}
 
-  '@types/node@20.14.14':
-    resolution: {integrity: sha512-d64f00982fS9YoOgJkAMolK7MN8Iq3TDdVjchbYHdEmjth/DHowx82GnoA+tVUAN+7vxfYUgAzi+JXbKNd2SDQ==}
+  '@types/node@20.14.15':
+    resolution: {integrity: sha512-Fz1xDMCF/B00/tYSVMlmK7hVeLh7jE5f3B7X1/hmV0MJBwE27KlS7EvD/Yp+z1lm8mVhwV5w+n8jOZG8AfTlKw==}
 
   '@types/nprogress@0.2.3':
     resolution: {integrity: sha512-k7kRA033QNtC+gLc4VPlfnue58CM1iQLgn1IMAU8VPHGOj7oIHPp9UlhedEnD/Gl8evoCjwkZjlBORtZ3JByUA==}
@@ -1403,8 +1403,8 @@ packages:
   electron-to-chromium@1.5.4:
     resolution: {integrity: sha512-orzA81VqLyIGUEA77YkVA1D+N+nNfl2isJVjjmOyrlxuooZ19ynb+dOlaDTqd/idKRS9lDCSBmtzM+kyCsMnkA==}
 
-  electron-updater@6.3.2:
-    resolution: {integrity: sha512-bEpuZ1IRnMtvZZaWeYi9ocX90Cnk+/impZ/08r6GQkfOMqECtKC2IjvxHcDk2VpWO8QZzK0+MUNaBiO81CGvQQ==}
+  electron-updater@6.3.3:
+    resolution: {integrity: sha512-Kj1u6kfyxUyatnspvKa6qhGn82rMZfUD03WOvCGJ12PyRss/AC8kkYsN9IrJihKTlN8nRwTjZ1JM2UUXoD0KsA==}
 
   electron@31.3.1:
     resolution: {integrity: sha512-9fiuWlRhBfygtcT+auRd/WdBK/f8LZZcrpx0RjpXhH2DPTP/PfnkC4JB1PW55qCbGbh4wAgkYbf4ExIag8oGCA==}
@@ -2894,11 +2894,11 @@ packages:
   symbol-tree@3.2.4:
     resolution: {integrity: sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==}
 
-  tailwind-merge@2.4.0:
-    resolution: {integrity: sha512-49AwoOQNKdqKPd9CViyH5wJoSKsCDjUlzL8DxuGp3P1FsGY36NJDAa18jLZcaHAUUuTj+JB8IAo8zWgBNvBF7A==}
+  tailwind-merge@2.5.0:
+    resolution: {integrity: sha512-a6Q/isR5XAo9IR7Hjh80BQDkn8PG9ONJpSO/U3vGzdKyKG125lPHNXdiPfeQ5X0EOG0qKlS/0qnxdBYkLlD6tA==}
 
-  tailwindcss@3.4.7:
-    resolution: {integrity: sha512-rxWZbe87YJb4OcSopb7up2Ba4U82BoiSGUdoDr3Ydrg9ckxFS/YWsvhN323GMcddgU65QRy7JndC7ahhInhvlQ==}
+  tailwindcss@3.4.9:
+    resolution: {integrity: sha512-1SEOvRr6sSdV5IDf9iC+NU4dhwdqzF4zKKq3sAbasUWHEM6lsMhX+eNN5gkPx1BvLFEnZQEUFbXnGj8Qlp83Pg==}
     engines: {node: '>=14.0.0'}
     hasBin: true
 
@@ -3598,27 +3598,27 @@ snapshots:
   '@jest/console@29.7.0':
     dependencies:
       '@jest/types': 29.6.3
-      '@types/node': 20.14.14
+      '@types/node': 20.14.15
       chalk: 4.1.2
       jest-message-util: 29.7.0
       jest-util: 29.7.0
       slash: 3.0.0
 
-  '@jest/core@29.7.0(ts-node@10.9.2(@types/node@20.14.14)(typescript@5.5.4))':
+  '@jest/core@29.7.0(ts-node@10.9.2(@types/node@20.14.15)(typescript@5.5.4))':
     dependencies:
       '@jest/console': 29.7.0
       '@jest/reporters': 29.7.0
       '@jest/test-result': 29.7.0
       '@jest/transform': 29.7.0
       '@jest/types': 29.6.3
-      '@types/node': 20.14.14
+      '@types/node': 20.14.15
       ansi-escapes: 4.3.2
       chalk: 4.1.2
       ci-info: 3.9.0
       exit: 0.1.2
       graceful-fs: 4.2.11
       jest-changed-files: 29.7.0
-      jest-config: 29.7.0(@types/node@20.14.14)(ts-node@10.9.2(@types/node@20.14.14)(typescript@5.5.4))
+      jest-config: 29.7.0(@types/node@20.14.15)(ts-node@10.9.2(@types/node@20.14.15)(typescript@5.5.4))
       jest-haste-map: 29.7.0
       jest-message-util: 29.7.0
       jest-regex-util: 29.6.3
@@ -3643,7 +3643,7 @@ snapshots:
     dependencies:
       '@jest/fake-timers': 29.7.0
       '@jest/types': 29.6.3
-      '@types/node': 20.14.14
+      '@types/node': 20.14.15
       jest-mock: 29.7.0
 
   '@jest/expect-utils@29.7.0':
@@ -3661,7 +3661,7 @@ snapshots:
     dependencies:
       '@jest/types': 29.6.3
       '@sinonjs/fake-timers': 10.3.0
-      '@types/node': 20.14.14
+      '@types/node': 20.14.15
       jest-message-util: 29.7.0
       jest-mock: 29.7.0
       jest-util: 29.7.0
@@ -3683,7 +3683,7 @@ snapshots:
       '@jest/transform': 29.7.0
       '@jest/types': 29.6.3
       '@jridgewell/trace-mapping': 0.3.25
-      '@types/node': 20.14.14
+      '@types/node': 20.14.15
       chalk: 4.1.2
       collect-v8-coverage: 1.0.2
       exit: 0.1.2
@@ -3753,7 +3753,7 @@ snapshots:
       '@jest/schemas': 29.6.3
       '@types/istanbul-lib-coverage': 2.0.6
       '@types/istanbul-reports': 3.0.4
-      '@types/node': 20.14.14
+      '@types/node': 20.14.15
       '@types/yargs': 17.0.32
       chalk: 4.1.2
 
@@ -3892,7 +3892,7 @@ snapshots:
     dependencies:
       '@types/http-cache-semantics': 4.0.4
       '@types/keyv': 3.1.4
-      '@types/node': 20.14.14
+      '@types/node': 20.14.15
       '@types/responselike': 1.0.3
 
   '@types/debug@4.1.12':
@@ -3913,11 +3913,11 @@ snapshots:
 
   '@types/fs-extra@9.0.13':
     dependencies:
-      '@types/node': 20.14.14
+      '@types/node': 20.14.15
 
   '@types/graceful-fs@4.1.9':
     dependencies:
-      '@types/node': 20.14.14
+      '@types/node': 20.14.15
 
   '@types/history@4.7.11': {}
 
@@ -3940,7 +3940,7 @@ snapshots:
 
   '@types/jsdom@20.0.1':
     dependencies:
-      '@types/node': 20.14.14
+      '@types/node': 20.14.15
       '@types/tough-cookie': 4.0.5
       parse5: 7.1.2
 
@@ -3948,11 +3948,11 @@ snapshots:
 
   '@types/keyv@3.1.4':
     dependencies:
-      '@types/node': 20.14.14
+      '@types/node': 20.14.15
 
   '@types/ms@0.7.34': {}
 
-  '@types/node@20.14.14':
+  '@types/node@20.14.15':
     dependencies:
       undici-types: 5.26.5
 
@@ -3960,7 +3960,7 @@ snapshots:
 
   '@types/plist@3.0.5':
     dependencies:
-      '@types/node': 20.14.14
+      '@types/node': 20.14.15
       xmlbuilder: 15.1.1
     optional: true
 
@@ -3989,7 +3989,7 @@ snapshots:
 
   '@types/responselike@1.0.3':
     dependencies:
-      '@types/node': 20.14.14
+      '@types/node': 20.14.15
 
   '@types/stack-utils@2.0.3': {}
 
@@ -4006,7 +4006,7 @@ snapshots:
 
   '@types/yauzl@2.10.3':
     dependencies:
-      '@types/node': 20.14.14
+      '@types/node': 20.14.15
     optional: true
 
   '@webassemblyjs/ast@1.12.1':
@@ -4600,13 +4600,13 @@ snapshots:
       buffer: 5.7.1
     optional: true
 
-  create-jest@29.7.0(@types/node@20.14.14)(ts-node@10.9.2(@types/node@20.14.14)(typescript@5.5.4)):
+  create-jest@29.7.0(@types/node@20.14.15)(ts-node@10.9.2(@types/node@20.14.15)(typescript@5.5.4)):
     dependencies:
       '@jest/types': 29.6.3
       chalk: 4.1.2
       exit: 0.1.2
       graceful-fs: 4.2.11
-      jest-config: 29.7.0(@types/node@20.14.14)(ts-node@10.9.2(@types/node@20.14.14)(typescript@5.5.4))
+      jest-config: 29.7.0(@types/node@20.14.15)(ts-node@10.9.2(@types/node@20.14.15)(typescript@5.5.4))
       jest-util: 29.7.0
       prompts: 2.4.2
     transitivePeerDependencies:
@@ -4801,7 +4801,7 @@ snapshots:
 
   electron-to-chromium@1.5.4: {}
 
-  electron-updater@6.3.2:
+  electron-updater@6.3.3:
     dependencies:
       builder-util-runtime: 9.2.5
       fs-extra: 10.1.0
@@ -4817,7 +4817,7 @@ snapshots:
   electron@31.3.1:
     dependencies:
       '@electron/get': 2.0.3
-      '@types/node': 20.14.14
+      '@types/node': 20.14.15
       extract-zip: 2.0.1
     transitivePeerDependencies:
       - supports-color
@@ -5346,7 +5346,7 @@ snapshots:
       '@jest/expect': 29.7.0
       '@jest/test-result': 29.7.0
       '@jest/types': 29.6.3
-      '@types/node': 20.14.14
+      '@types/node': 20.14.15
       chalk: 4.1.2
       co: 4.6.0
       dedent: 1.5.1
@@ -5366,16 +5366,16 @@ snapshots:
       - babel-plugin-macros
       - supports-color
 
-  jest-cli@29.7.0(@types/node@20.14.14)(ts-node@10.9.2(@types/node@20.14.14)(typescript@5.5.4)):
+  jest-cli@29.7.0(@types/node@20.14.15)(ts-node@10.9.2(@types/node@20.14.15)(typescript@5.5.4)):
     dependencies:
-      '@jest/core': 29.7.0(ts-node@10.9.2(@types/node@20.14.14)(typescript@5.5.4))
+      '@jest/core': 29.7.0(ts-node@10.9.2(@types/node@20.14.15)(typescript@5.5.4))
       '@jest/test-result': 29.7.0
       '@jest/types': 29.6.3
       chalk: 4.1.2
-      create-jest: 29.7.0(@types/node@20.14.14)(ts-node@10.9.2(@types/node@20.14.14)(typescript@5.5.4))
+      create-jest: 29.7.0(@types/node@20.14.15)(ts-node@10.9.2(@types/node@20.14.15)(typescript@5.5.4))
       exit: 0.1.2
       import-local: 3.1.0
-      jest-config: 29.7.0(@types/node@20.14.14)(ts-node@10.9.2(@types/node@20.14.14)(typescript@5.5.4))
+      jest-config: 29.7.0(@types/node@20.14.15)(ts-node@10.9.2(@types/node@20.14.15)(typescript@5.5.4))
       jest-util: 29.7.0
       jest-validate: 29.7.0
       yargs: 17.7.2
@@ -5385,7 +5385,7 @@ snapshots:
       - supports-color
       - ts-node
 
-  jest-config@29.7.0(@types/node@20.14.14)(ts-node@10.9.2(@types/node@20.14.14)(typescript@5.5.4)):
+  jest-config@29.7.0(@types/node@20.14.15)(ts-node@10.9.2(@types/node@20.14.15)(typescript@5.5.4)):
     dependencies:
       '@babel/core': 7.24.3
       '@jest/test-sequencer': 29.7.0
@@ -5410,8 +5410,8 @@ snapshots:
       slash: 3.0.0
       strip-json-comments: 3.1.1
     optionalDependencies:
-      '@types/node': 20.14.14
-      ts-node: 10.9.2(@types/node@20.14.14)(typescript@5.5.4)
+      '@types/node': 20.14.15
+      ts-node: 10.9.2(@types/node@20.14.15)(typescript@5.5.4)
     transitivePeerDependencies:
       - babel-plugin-macros
       - supports-color
@@ -5441,7 +5441,7 @@ snapshots:
       '@jest/fake-timers': 29.7.0
       '@jest/types': 29.6.3
       '@types/jsdom': 20.0.1
-      '@types/node': 20.14.14
+      '@types/node': 20.14.15
       jest-mock: 29.7.0
       jest-util: 29.7.0
       jsdom: 20.0.3
@@ -5455,7 +5455,7 @@ snapshots:
       '@jest/environment': 29.7.0
       '@jest/fake-timers': 29.7.0
       '@jest/types': 29.6.3
-      '@types/node': 20.14.14
+      '@types/node': 20.14.15
       jest-mock: 29.7.0
       jest-util: 29.7.0
 
@@ -5465,7 +5465,7 @@ snapshots:
     dependencies:
       '@jest/types': 29.6.3
       '@types/graceful-fs': 4.1.9
-      '@types/node': 20.14.14
+      '@types/node': 20.14.15
       anymatch: 3.1.3
       fb-watchman: 2.0.2
       graceful-fs: 4.2.11
@@ -5504,7 +5504,7 @@ snapshots:
   jest-mock@29.7.0:
     dependencies:
       '@jest/types': 29.6.3
-      '@types/node': 20.14.14
+      '@types/node': 20.14.15
       jest-util: 29.7.0
 
   jest-pnp-resolver@1.2.3(jest-resolve@29.7.0):
@@ -5539,7 +5539,7 @@ snapshots:
       '@jest/test-result': 29.7.0
       '@jest/transform': 29.7.0
       '@jest/types': 29.6.3
-      '@types/node': 20.14.14
+      '@types/node': 20.14.15
       chalk: 4.1.2
       emittery: 0.13.1
       graceful-fs: 4.2.11
@@ -5567,7 +5567,7 @@ snapshots:
       '@jest/test-result': 29.7.0
       '@jest/transform': 29.7.0
       '@jest/types': 29.6.3
-      '@types/node': 20.14.14
+      '@types/node': 20.14.15
       chalk: 4.1.2
       cjs-module-lexer: 1.2.3
       collect-v8-coverage: 1.0.2
@@ -5613,7 +5613,7 @@ snapshots:
   jest-util@29.7.0:
     dependencies:
       '@jest/types': 29.6.3
-      '@types/node': 20.14.14
+      '@types/node': 20.14.15
       chalk: 4.1.2
       ci-info: 3.9.0
       graceful-fs: 4.2.11
@@ -5632,7 +5632,7 @@ snapshots:
     dependencies:
       '@jest/test-result': 29.7.0
       '@jest/types': 29.6.3
-      '@types/node': 20.14.14
+      '@types/node': 20.14.15
       ansi-escapes: 4.3.2
       chalk: 4.1.2
       emittery: 0.13.1
@@ -5641,23 +5641,23 @@ snapshots:
 
   jest-worker@27.5.1:
     dependencies:
-      '@types/node': 20.14.14
+      '@types/node': 20.14.15
       merge-stream: 2.0.0
       supports-color: 8.1.1
 
   jest-worker@29.7.0:
     dependencies:
-      '@types/node': 20.14.14
+      '@types/node': 20.14.15
       jest-util: 29.7.0
       merge-stream: 2.0.0
       supports-color: 8.1.1
 
-  jest@29.7.0(@types/node@20.14.14)(ts-node@10.9.2(@types/node@20.14.14)(typescript@5.5.4)):
+  jest@29.7.0(@types/node@20.14.15)(ts-node@10.9.2(@types/node@20.14.15)(typescript@5.5.4)):
     dependencies:
-      '@jest/core': 29.7.0(ts-node@10.9.2(@types/node@20.14.14)(typescript@5.5.4))
+      '@jest/core': 29.7.0(ts-node@10.9.2(@types/node@20.14.15)(typescript@5.5.4))
       '@jest/types': 29.6.3
       import-local: 3.1.0
-      jest-cli: 29.7.0(@types/node@20.14.14)(ts-node@10.9.2(@types/node@20.14.14)(typescript@5.5.4))
+      jest-cli: 29.7.0(@types/node@20.14.15)(ts-node@10.9.2(@types/node@20.14.15)(typescript@5.5.4))
     transitivePeerDependencies:
       - '@types/node'
       - babel-plugin-macros
@@ -6017,13 +6017,13 @@ snapshots:
       camelcase-css: 2.0.1
       postcss: 8.4.41
 
-  postcss-load-config@4.0.2(postcss@8.4.41)(ts-node@10.9.2(@types/node@20.14.14)(typescript@5.5.4)):
+  postcss-load-config@4.0.2(postcss@8.4.41)(ts-node@10.9.2(@types/node@20.14.15)(typescript@5.5.4)):
     dependencies:
       lilconfig: 3.1.1
       yaml: 2.4.1
     optionalDependencies:
       postcss: 8.4.41
-      ts-node: 10.9.2(@types/node@20.14.14)(typescript@5.5.4)
+      ts-node: 10.9.2(@types/node@20.14.15)(typescript@5.5.4)
 
   postcss-loader@8.1.1(postcss@8.4.41)(typescript@5.5.4)(webpack@5.93.0(webpack-cli@5.1.4)):
     dependencies:
@@ -6430,9 +6430,9 @@ snapshots:
 
   symbol-tree@3.2.4: {}
 
-  tailwind-merge@2.4.0: {}
+  tailwind-merge@2.5.0: {}
 
-  tailwindcss@3.4.7(ts-node@10.9.2(@types/node@20.14.14)(typescript@5.5.4)):
+  tailwindcss@3.4.9(ts-node@10.9.2(@types/node@20.14.15)(typescript@5.5.4)):
     dependencies:
       '@alloc/quick-lru': 5.2.0
       arg: 5.0.2
@@ -6451,7 +6451,7 @@ snapshots:
       postcss: 8.4.41
       postcss-import: 15.1.0(postcss@8.4.41)
       postcss-js: 4.0.1(postcss@8.4.41)
-      postcss-load-config: 4.0.2(postcss@8.4.41)(ts-node@10.9.2(@types/node@20.14.14)(typescript@5.5.4))
+      postcss-load-config: 4.0.2(postcss@8.4.41)(ts-node@10.9.2(@types/node@20.14.15)(typescript@5.5.4))
       postcss-nested: 6.0.1(postcss@8.4.41)
       postcss-selector-parser: 6.0.16
       resolve: 1.22.8
@@ -6546,12 +6546,12 @@ snapshots:
 
   ts-interface-checker@0.1.13: {}
 
-  ts-jest@29.2.4(@babel/core@7.24.3)(@jest/transform@29.7.0)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.24.3))(jest@29.7.0(@types/node@20.14.14)(ts-node@10.9.2(@types/node@20.14.14)(typescript@5.5.4)))(typescript@5.5.4):
+  ts-jest@29.2.4(@babel/core@7.24.3)(@jest/transform@29.7.0)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.24.3))(jest@29.7.0(@types/node@20.14.15)(ts-node@10.9.2(@types/node@20.14.15)(typescript@5.5.4)))(typescript@5.5.4):
     dependencies:
       bs-logger: 0.2.6
       ejs: 3.1.10
       fast-json-stable-stringify: 2.1.0
-      jest: 29.7.0(@types/node@20.14.14)(ts-node@10.9.2(@types/node@20.14.14)(typescript@5.5.4))
+      jest: 29.7.0(@types/node@20.14.15)(ts-node@10.9.2(@types/node@20.14.15)(typescript@5.5.4))
       jest-util: 29.7.0
       json5: 2.2.3
       lodash.memoize: 4.1.2
@@ -6575,14 +6575,14 @@ snapshots:
       typescript: 5.5.4
       webpack: 5.93.0(webpack-cli@5.1.4)
 
-  ts-node@10.9.2(@types/node@20.14.14)(typescript@5.5.4):
+  ts-node@10.9.2(@types/node@20.14.15)(typescript@5.5.4):
     dependencies:
       '@cspotcode/source-map-support': 0.8.1
       '@tsconfig/node10': 1.0.11
       '@tsconfig/node12': 1.0.11
       '@tsconfig/node14': 1.0.3
       '@tsconfig/node16': 1.0.4
-      '@types/node': 20.14.14
+      '@types/node': 20.14.15
       acorn: 8.11.3
       acorn-walk: 8.3.2
       arg: 4.1.3
diff --git a/src/__mocks__/utils.ts b/src/__mocks__/utils.ts
index c4c0c756..cf1c57cb 100644
--- a/src/__mocks__/utils.ts
+++ b/src/__mocks__/utils.ts
@@ -3,3 +3,10 @@ export function setPlatform(platform: NodeJS.Platform) {
     value: platform,
   });
 }
+
+/**
+ * Ensure stable snapshots for our randomized emoji use-cases
+ */
+export function ensureStableEmojis() {
+  global.Math.random = jest.fn(() => 0.1);
+}
diff --git a/src/context/App.tsx b/src/context/App.tsx
index cb7dd667..77f7167e 100644
--- a/src/context/App.tsx
+++ b/src/context/App.tsx
@@ -164,8 +164,9 @@ export const AppProvider = ({ children }: { children: ReactNode }) => {
 
   useEffect(() => {
     ipcRenderer.on('gitify:reset-app', () => {
-      setAuth(defaultAuth);
       clearState();
+      setAuth(defaultAuth);
+      setSettings(defaultSettings);
     });
   }, []);
 
diff --git a/src/electron/main.js b/src/electron/main.js
index dd36b70c..34d0b975 100644
--- a/src/electron/main.js
+++ b/src/electron/main.js
@@ -268,6 +268,7 @@ function takeScreenshot() {
 
 function resetApp() {
   const cancelButtonId = 0;
+  const resetButtonId = 1;
 
   const response = dialog.showMessageBoxSync(mb.window, {
     type: 'warning',
@@ -279,10 +280,8 @@ function resetApp() {
     cancelId: cancelButtonId,
   });
 
-  if (response === cancelButtonId) {
-    return;
+  if (response === resetButtonId) {
+    mb.window.webContents.send('gitify:reset-app');
+    mb.app.quit();
   }
-
-  mb.window.webContents.send('gitify:reset-app');
-  mb.app.quit();
 }
diff --git a/src/hooks/useNotifications.ts b/src/hooks/useNotifications.ts
index a6d39293..31ff7d20 100644
--- a/src/hooks/useNotifications.ts
+++ b/src/hooks/useNotifications.ts
@@ -1,3 +1,4 @@
+import log from 'electron-log';
 import { useCallback, useState } from 'react';
 import type {
   AccountNotifications,
@@ -109,10 +110,11 @@ export const useNotifications = (): NotificationsState => {
 
         setNotifications(updatedNotifications);
         setTrayIconColor(updatedNotifications);
-        setStatus('success');
       } catch (err) {
-        setStatus('success');
+        log.error('Error occurred while marking notification as read', err);
       }
+
+      setStatus('success');
     },
     [notifications],
   );
@@ -138,10 +140,11 @@ export const useNotifications = (): NotificationsState => {
 
         setNotifications(updatedNotifications);
         setTrayIconColor(updatedNotifications);
-        setStatus('success');
       } catch (err) {
-        setStatus('success');
+        log.error('Error occurred while marking notification as done', err);
       }
+
+      setStatus('success');
     },
     [notifications],
   );
@@ -157,10 +160,14 @@ export const useNotifications = (): NotificationsState => {
           notification.account.token,
         );
         await markNotificationRead(state, notification);
-        setStatus('success');
       } catch (err) {
-        setStatus('success');
+        log.error(
+          'Error occurred while unsubscribing from notification thread',
+          err,
+        );
       }
+
+      setStatus('success');
     },
     [markNotificationRead],
   );
@@ -187,10 +194,14 @@ export const useNotifications = (): NotificationsState => {
 
         setNotifications(updatedNotifications);
         setTrayIconColor(updatedNotifications);
-        setStatus('success');
       } catch (err) {
-        setStatus('success');
+        log.error(
+          'Error occurred while marking repository notifications as read',
+          err,
+        );
       }
+
+      setStatus('success');
     },
     [notifications],
   );
@@ -230,10 +241,14 @@ export const useNotifications = (): NotificationsState => {
 
         setNotifications(updatedNotifications);
         setTrayIconColor(updatedNotifications);
-        setStatus('success');
       } catch (err) {
-        setStatus('success');
+        log.error(
+          'Error occurred while marking repository notifications as done',
+          err,
+        );
       }
+
+      setStatus('success');
     },
     [notifications, markNotificationDone],
   );
diff --git a/src/routes/Accounts.tsx b/src/routes/Accounts.tsx
index 60e77c57..774a5d39 100644
--- a/src/routes/Accounts.tsx
+++ b/src/routes/Accounts.tsx
@@ -3,6 +3,8 @@ import {
   PersonIcon,
   PlusIcon,
   SignOutIcon,
+  StarFillIcon,
+  StarIcon,
 } from '@primer/octicons-react';
 
 import { type FC, useCallback, useContext } from 'react';
@@ -12,17 +14,19 @@ import { AuthMethodIcon } from '../components/icons/AuthMethodIcon';
 import { PlatformIcon } from '../components/icons/PlatformIcon';
 import { AppContext } from '../context/App';
 import { BUTTON_CLASS_NAME } from '../styles/gitify';
-import { type Account, Size } from '../types';
+import { type Account, IconColor, Size } from '../types';
 import { getAccountUUID } from '../utils/auth/utils';
+import { cn } from '../utils/cn';
 import { updateTrayIcon, updateTrayTitle } from '../utils/comms';
 import {
   openAccountProfile,
   openDeveloperSettings,
   openHost,
 } from '../utils/links';
+import { saveState } from '../utils/storage';
 
 export const AccountsRoute: FC = () => {
-  const { auth, logoutFromAccount } = useContext(AppContext);
+  const { auth, settings, logoutFromAccount } = useContext(AppContext);
   const navigate = useNavigate();
 
   const logoutAccount = useCallback(
@@ -35,6 +39,12 @@ export const AccountsRoute: FC = () => {
     [logoutFromAccount],
   );
 
+  const setAsPrimaryAccount = useCallback((account: Account) => {
+    auth.accounts = [account, ...auth.accounts.filter((a) => a !== account)];
+    saveState({ auth, settings });
+    navigate('/accounts', { replace: true });
+  }, []);
+
   const loginWithPersonalAccessToken = useCallback(() => {
     return navigate('/login-personal-access-token', { replace: true });
   }, []);
@@ -48,7 +58,7 @@ export const AccountsRoute: FC = () => {
       <Header icon={PersonIcon}>Accounts</Header>
       <div className="flex-grow overflow-x-auto px-8">
         <div className="mt-4 flex flex-col text-sm">
-          {auth.accounts.map((account) => (
+          {auth.accounts.map((account, i) => (
             <div
               key={getAccountUUID(account)}
               className="mb-4 flex items-center justify-between rounded-md bg-gray-100 p-2 dark:bg-gray-sidebar"
@@ -94,6 +104,31 @@ export const AccountsRoute: FC = () => {
                 </div>
               </div>
               <div>
+                <button
+                  type="button"
+                  className={cn(BUTTON_CLASS_NAME, 'cursor-default')}
+                  title="Primary account"
+                  hidden={i !== 0}
+                >
+                  <StarFillIcon
+                    size={Size.XLARGE}
+                    className={IconColor.YELLOW}
+                    aria-label="Primary account"
+                  />
+                </button>
+                <button
+                  type="button"
+                  className={BUTTON_CLASS_NAME}
+                  title="Set as primary account"
+                  onClick={() => setAsPrimaryAccount(account)}
+                  hidden={i === 0}
+                >
+                  <StarIcon
+                    size={Size.XLARGE}
+                    className={IconColor.YELLOW}
+                    aria-label="Set as primary account"
+                  />
+                </button>
                 <button
                   type="button"
                   className={BUTTON_CLASS_NAME}
diff --git a/src/routes/Login.tsx b/src/routes/Login.tsx
index 6ac1f879..325c019d 100644
--- a/src/routes/Login.tsx
+++ b/src/routes/Login.tsx
@@ -23,7 +23,7 @@ export const LoginRoute: FC = () => {
     try {
       await login();
     } catch (err) {
-      // Skip
+      log.error('Auth: failed to login with GitHub', err);
     }
   }, []); */
 
diff --git a/src/routes/LoginWithOAuthApp.tsx b/src/routes/LoginWithOAuthApp.tsx
index 9d0e7df3..49567005 100644
--- a/src/routes/LoginWithOAuthApp.tsx
+++ b/src/routes/LoginWithOAuthApp.tsx
@@ -1,4 +1,5 @@
 import { BookIcon, PersonIcon, SignInIcon } from '@primer/octicons-react';
+import log from 'electron-log';
 import { type FC, useCallback, useContext } from 'react';
 import { Form, type FormRenderProps } from 'react-final-form';
 import { Header } from '../components/Header';
@@ -76,6 +77,7 @@ export const LoginWithOAuthApp: FC = () => {
                 disabled={!values.hostname}
                 icon={{ icon: PersonIcon, size: Size.XSMALL }}
                 url={getNewOAuthAppURL(values.hostname)}
+                size="xs"
               >
                 Create new OAuth App
               </Button>
@@ -100,7 +102,10 @@ export const LoginWithOAuthApp: FC = () => {
             className="mt-2"
             icon={{ icon: BookIcon, size: Size.XSMALL }}
             url={Constants.GITHUB_DOCS.OAUTH_URL}
-          />
+            size="xs"
+          >
+            Docs
+          </Button>
 
           <Button
             name="Login"
@@ -109,7 +114,9 @@ export const LoginWithOAuthApp: FC = () => {
             icon={{ icon: SignInIcon, size: Size.MEDIUM }}
             disabled={submitting || pristine}
             type="submit"
-          />
+          >
+            Login
+          </Button>
         </div>
       </form>
     );
@@ -120,6 +127,7 @@ export const LoginWithOAuthApp: FC = () => {
       try {
         await loginWithOAuthApp(data as LoginOAuthAppOptions);
       } catch (err) {
+        log.error('Auth: Failed to login with oauth app', err);
         // Skip
       }
     },
diff --git a/src/routes/LoginWithPersonalAccessToken.tsx b/src/routes/LoginWithPersonalAccessToken.tsx
index e792ef12..2f76d4f1 100644
--- a/src/routes/LoginWithPersonalAccessToken.tsx
+++ b/src/routes/LoginWithPersonalAccessToken.tsx
@@ -1,4 +1,5 @@
 import { BookIcon, KeyIcon, SignInIcon } from '@primer/octicons-react';
+import log from 'electron-log';
 import { type FC, useCallback, useContext, useState } from 'react';
 import { Form, type FormRenderProps } from 'react-final-form';
 import { useNavigate } from 'react-router-dom';
@@ -57,37 +58,39 @@ export const LoginWithPersonalAccessToken: FC = () => {
           name="hostname"
           label="Hostname"
           placeholder="github.company.com"
-          helpText={
-            <div className="mt-1 italic">
-              Change only if you are using GitHub Enterprise Server.
-            </div>
-          }
-        />
-
-        <FieldInput
-          name="token"
-          label="Token"
-          placeholder="The 40 characters token generated on GitHub"
           helpText={
             <div>
-              <div>
+              <div className="mt-1 italic">
+                Change only if you are using GitHub Enterprise Server.
+              </div>
+              <div className="mt-3">
                 <Button
                   label="Generate a PAT"
                   disabled={!values.hostname}
                   icon={{ icon: KeyIcon, size: Size.XSMALL }}
                   url={getNewTokenURL(values.hostname)}
+                  size="xs"
                 >
                   Generate a PAT
                 </Button>
-                <span className="mx-1">on GitHub and paste above.</span>
+                <span className="mx-1">
+                  on GitHub then paste your{' '}
+                  <span className="italic">token</span> below.
+                </span>
               </div>
               <div className="mt-1 italic">
-                The required scopes will be selected for you.
+                The required scopes will be automatically selected for you.
               </div>
             </div>
           }
         />
 
+        <FieldInput
+          name="token"
+          label="Token"
+          placeholder="The 40 characters token generated on GitHub"
+        />
+
         {!isValidToken && (
           <div className="mt-4 text-sm font-medium text-red-500">
             This token could not be validated with {values.hostname}.
@@ -99,6 +102,7 @@ export const LoginWithPersonalAccessToken: FC = () => {
             label="GitHub Docs"
             icon={{ icon: BookIcon, size: Size.XSMALL }}
             url={Constants.GITHUB_DOCS.PAT_URL}
+            size="xs"
           >
             Docs
           </Button>
@@ -125,6 +129,7 @@ export const LoginWithPersonalAccessToken: FC = () => {
         );
         navigate(-1);
       } catch (err) {
+        log.error('Auth: failed to login with personal access token', err);
         setIsValidToken(false);
       }
     },
diff --git a/src/utils/api/client.ts b/src/utils/api/client.ts
index d3b35837..a2f133e8 100644
--- a/src/utils/api/client.ts
+++ b/src/utils/api/client.ts
@@ -226,7 +226,7 @@ export async function getHtmlUrl(url: Link, token: Token): Promise<string> {
     const response = (await apiRequestAuth(url, 'GET', token)).data;
     return response.html_url;
   } catch (err) {
-    log.error('Failed to get html url');
+    log.error('Error occurred while fetching notification html url', err);
   }
 }
 
@@ -272,5 +272,10 @@ export async function getLatestDiscussion(
         (discussion) => discussion.title === notification.subject.title,
       )[0] ?? null
     );
-  } catch (err) {}
+  } catch (err) {
+    log.error(
+      'Error occurred while fetching notification latest discussion',
+      err,
+    );
+  }
 }
diff --git a/src/utils/comms.ts b/src/utils/comms.ts
index 13cef346..0a11fa0c 100644
--- a/src/utils/comms.ts
+++ b/src/utils/comms.ts
@@ -1,4 +1,5 @@
 import { ipcRenderer, shell } from 'electron';
+import { defaultSettings } from '../context/App';
 import { type Link, OpenPreference } from '../types';
 import Constants from './constants';
 import { loadState } from './storage';
@@ -8,8 +9,12 @@ export function openExternalLink(url: Link): void {
     // Load the state from local storage to avoid having to pass settings as a parameter
     const { settings } = loadState();
 
+    const openPreference = settings
+      ? settings.openLinks
+      : defaultSettings.openLinks;
+
     shell.openExternal(url, {
-      activate: settings.openLinks === OpenPreference.FOREGROUND,
+      activate: openPreference === OpenPreference.FOREGROUND,
     });
   }
 }
diff --git a/src/utils/notifications.ts b/src/utils/notifications.ts
index 35ad9d2a..0a2dc618 100644
--- a/src/utils/notifications.ts
+++ b/src/utils/notifications.ts
@@ -1,3 +1,4 @@
+import log from 'electron-log';
 import type {
   AccountNotifications,
   GitifyState,
@@ -148,6 +149,10 @@ export async function getAllNotifications(
             error: null,
           };
         } catch (error) {
+          log.error(
+            'Error occurred while fetching account notifications',
+            error,
+          );
           return {
             account: accountNotifications.account,
             notifications: [],
diff --git a/src/utils/storage.ts b/src/utils/storage.ts
index 90d4d47f..74686be2 100644
--- a/src/utils/storage.ts
+++ b/src/utils/storage.ts
@@ -1,13 +1,9 @@
-import { defaultAuth, defaultSettings } from '../context/App';
 import type { GitifyState } from '../types';
 import { Constants } from './constants';
 
 export function loadState(): GitifyState {
   const existing = localStorage.getItem(Constants.STORAGE_KEY);
-  const { auth, settings } = (existing && JSON.parse(existing)) || {
-    auth: defaultAuth,
-    settings: defaultSettings,
-  };
+  const { auth, settings } = (existing && JSON.parse(existing)) || {};
   return { auth, settings };
 }
 


Test patch:
diff --git a/src/components/AccountNotifications.test.tsx b/src/components/AccountNotifications.test.tsx
index 7df67540..d0b3556f 100644
--- a/src/components/AccountNotifications.test.tsx
+++ b/src/components/AccountNotifications.test.tsx
@@ -1,5 +1,6 @@
 import { act, fireEvent, render, screen } from '@testing-library/react';
 import { mockGitHubCloudAccount, mockSettings } from '../__mocks__/state-mocks';
+import { ensureStableEmojis } from '../__mocks__/utils';
 import { AppContext } from '../context/App';
 import { GroupBy } from '../types';
 import { mockGitHubNotifications } from '../utils/api/__mocks__/response-mocks';
@@ -11,10 +12,8 @@ jest.mock('./RepositoryNotifications', () => ({
 }));
 
 describe('components/AccountNotifications.tsx', () => {
-  // The read emoji randomly rotates, but then the snapshots would never match
-  // Have to make it consistent so the emojis are always the same
   beforeEach(() => {
-    global.Math.random = jest.fn(() => 0.1);
+    ensureStableEmojis();
   });
 
   it('should render itself - group notifications by repositories', () => {
diff --git a/src/components/AllRead.test.tsx b/src/components/AllRead.test.tsx
index cd12d4a1..c58becdd 100644
--- a/src/components/AllRead.test.tsx
+++ b/src/components/AllRead.test.tsx
@@ -1,11 +1,10 @@
 import { render } from '@testing-library/react';
+import { ensureStableEmojis } from '../__mocks__/utils';
 import { AllRead } from './AllRead';
 
 describe('components/AllRead.tsx', () => {
-  // The read emoji randomly rotates, but then the snapshots would never match
-  // Have to make it consistent so the emojis are always the same
   beforeEach(() => {
-    global.Math.random = jest.fn(() => 0.1);
+    ensureStableEmojis();
   });
 
   it('should render itself & its children', () => {
diff --git a/src/components/settings/SettingsFooter.test.tsx b/src/components/settings/SettingsFooter.test.tsx
index 36559342..86b624f0 100644
--- a/src/components/settings/SettingsFooter.test.tsx
+++ b/src/components/settings/SettingsFooter.test.tsx
@@ -14,11 +14,6 @@ jest.mock('react-router-dom', () => ({
 global.ResizeObserver = require('resize-observer-polyfill');
 
 describe('routes/components/settings/SettingsFooter.tsx', () => {
-  afterEach(() => {
-    jest.clearAllMocks();
-    process.env = originalEnv;
-  });
-
   let originalEnv: NodeJS.ProcessEnv;
 
   beforeEach(() => {
@@ -26,6 +21,11 @@ describe('routes/components/settings/SettingsFooter.tsx', () => {
     originalEnv = process.env;
   });
 
+  afterEach(() => {
+    jest.clearAllMocks();
+    process.env = originalEnv;
+  });
+
   describe('app version', () => {
     it('should show production app version', async () => {
       process.env = {
diff --git a/src/hooks/useNotifications.test.ts b/src/hooks/useNotifications.test.ts
index 730364ea..1b014a12 100644
--- a/src/hooks/useNotifications.test.ts
+++ b/src/hooks/useNotifications.test.ts
@@ -2,6 +2,7 @@ import { act, renderHook, waitFor } from '@testing-library/react';
 import axios, { AxiosError } from 'axios';
 import nock from 'nock';
 
+import log from 'electron-log';
 import {
   mockAuth,
   mockGitHubCloudAccount,
@@ -16,10 +17,13 @@ import { Errors } from '../utils/constants';
 import { useNotifications } from './useNotifications';
 
 describe('hooks/useNotifications.ts', () => {
+  const logErrorSpy = jest.spyOn(log, 'error').mockImplementation();
+
   beforeEach(() => {
     // axios will default to using the XHR adapter which can't be intercepted
     // by nock. So, configure axios to use the node adapter.
     axios.defaults.adapter = 'http';
+    logErrorSpy.mockReset();
   });
 
   const id = mockSingleNotification.id;
@@ -294,6 +298,7 @@ describe('hooks/useNotifications.ts', () => {
       });
 
       expect(result.current.globalError).toBe(Errors.BAD_CREDENTIALS);
+      expect(logErrorSpy).toHaveBeenCalledTimes(2);
     });
 
     it('should fetch notifications with different failures', async () => {
@@ -336,6 +341,7 @@ describe('hooks/useNotifications.ts', () => {
       });
 
       expect(result.current.globalError).toBeNull();
+      expect(logErrorSpy).toHaveBeenCalledTimes(2);
     });
   });
 
@@ -374,6 +380,7 @@ describe('hooks/useNotifications.ts', () => {
       });
 
       expect(result.current.notifications.length).toBe(0);
+      expect(logErrorSpy).toHaveBeenCalledTimes(1);
     });
   });
 
@@ -412,6 +419,7 @@ describe('hooks/useNotifications.ts', () => {
       });
 
       expect(result.current.notifications.length).toBe(0);
+      expect(logErrorSpy).toHaveBeenCalledTimes(1);
     });
   });
 
@@ -470,13 +478,14 @@ describe('hooks/useNotifications.ts', () => {
       });
 
       expect(result.current.notifications.length).toBe(0);
+      expect(logErrorSpy).toHaveBeenCalledTimes(1);
     });
   });
 
   describe('markRepoNotificationsRead', () => {
     const repoSlug = 'gitify-app/notifications-test';
 
-    it("should mark a repository's notifications as read with success", async () => {
+    it('should mark repository notifications as read with success', async () => {
       nock('https://api.github.com/')
         .put(`/repos/${repoSlug}/notifications`)
         .reply(200);
@@ -497,7 +506,7 @@ describe('hooks/useNotifications.ts', () => {
       expect(result.current.notifications.length).toBe(0);
     });
 
-    it("should mark a repository's notifications as read with failure", async () => {
+    it('should mark repository notifications as read with failure', async () => {
       nock('https://api.github.com/')
         .put(`/repos/${repoSlug}/notifications`)
         .reply(400);
@@ -516,11 +525,12 @@ describe('hooks/useNotifications.ts', () => {
       });
 
       expect(result.current.notifications.length).toBe(0);
+      expect(logErrorSpy).toHaveBeenCalledTimes(1);
     });
   });
 
   describe('markRepoNotificationsDone', () => {
-    it("should mark a repository's notifications as done with success", async () => {
+    it('should mark repository notifications as done with success', async () => {
       nock('https://api.github.com/')
         .delete(`/notifications/threads/${id}`)
         .reply(200);
@@ -541,7 +551,7 @@ describe('hooks/useNotifications.ts', () => {
       expect(result.current.notifications.length).toBe(0);
     });
 
-    it("should mark a repository's notifications as done with failure", async () => {
+    it('should mark repository notifications as done with failure', async () => {
       nock('https://api.github.com/')
         .delete(`/notifications/threads/${id}`)
         .reply(400);
diff --git a/src/routes/__snapshots__/Accounts.test.tsx.snap b/src/routes/__snapshots__/Accounts.test.tsx.snap
index da96fff2..d86dd878 100644
--- a/src/routes/__snapshots__/Accounts.test.tsx.snap
+++ b/src/routes/__snapshots__/Accounts.test.tsx.snap
@@ -142,6 +142,49 @@ exports[`routes/Accounts.tsx General should render itself & its children 1`] = `
           </div>
         </div>
         <div>
+          <button
+            class="hover:text-gray-500 py-1 px-2 my-1 mx-2 focus:outline-none cursor-default"
+            title="Primary account"
+            type="button"
+          >
+            <svg
+              aria-label="Primary account"
+              class="text-yellow-500 dark:text-yellow-300"
+              fill="currentColor"
+              focusable="false"
+              height="20"
+              role="img"
+              style="display: inline-block; user-select: none; vertical-align: text-bottom; overflow: visible;"
+              viewBox="0 0 16 16"
+              width="20"
+            >
+              <path
+                d="M8 .25a.75.75 0 0 1 .673.418l1.882 3.815 4.21.612a.75.75 0 0 1 .416 1.279l-3.046 2.97.719 4.192a.751.751 0 0 1-1.088.791L8 12.347l-3.766 1.98a.75.75 0 0 1-1.088-.79l.72-4.194L.818 6.374a.75.75 0 0 1 .416-1.28l4.21-.611L7.327.668A.75.75 0 0 1 8 .25Z"
+              />
+            </svg>
+          </button>
+          <button
+            class="hover:text-gray-500 py-1 px-2 my-1 mx-2 focus:outline-none"
+            hidden=""
+            title="Set as primary account"
+            type="button"
+          >
+            <svg
+              aria-label="Set as primary account"
+              class="text-yellow-500 dark:text-yellow-300"
+              fill="currentColor"
+              focusable="false"
+              height="20"
+              role="img"
+              style="display: inline-block; user-select: none; vertical-align: text-bottom; overflow: visible;"
+              viewBox="0 0 16 16"
+              width="20"
+            >
+              <path
+                d="M8 .25a.75.75 0 0 1 .673.418l1.882 3.815 4.21.612a.75.75 0 0 1 .416 1.279l-3.046 2.97.719 4.192a.751.751 0 0 1-1.088.791L8 12.347l-3.766 1.98a.75.75 0 0 1-1.088-.79l.72-4.194L.818 6.374a.75.75 0 0 1 .416-1.28l4.21-.611L7.327.668A.75.75 0 0 1 8 .25Zm0 2.445L6.615 5.5a.75.75 0 0 1-.564.41l-3.097.45 2.24 2.184a.75.75 0 0 1 .216.664l-.528 3.084 2.769-1.456a.75.75 0 0 1 .698 0l2.77 1.456-.53-3.084a.75.75 0 0 1 .216-.664l2.24-2.183-3.096-.45a.75.75 0 0 1-.564-.41L8 2.694Z"
+              />
+            </svg>
+          </button>
           <button
             class="hover:text-gray-500 py-1 px-2 my-1 mx-2 focus:outline-none"
             title="Logout octocat"
@@ -247,6 +290,49 @@ exports[`routes/Accounts.tsx General should render itself & its children 1`] = `
           </div>
         </div>
         <div>
+          <button
+            class="hover:text-gray-500 py-1 px-2 my-1 mx-2 focus:outline-none cursor-default"
+            hidden=""
+            title="Primary account"
+            type="button"
+          >
+            <svg
+              aria-label="Primary account"
+              class="text-yellow-500 dark:text-yellow-300"
+              fill="currentColor"
+              focusable="false"
+              height="20"
+              role="img"
+              style="display: inline-block; user-select: none; vertical-align: text-bottom; overflow: visible;"
+              viewBox="0 0 16 16"
+              width="20"
+            >
+              <path
+                d="M8 .25a.75.75 0 0 1 .673.418l1.882 3.815 4.21.612a.75.75 0 0 1 .416 1.279l-3.046 2.97.719 4.192a.751.751 0 0 1-1.088.791L8 12.347l-3.766 1.98a.75.75 0 0 1-1.088-.79l.72-4.194L.818 6.374a.75.75 0 0 1 .416-1.28l4.21-.611L7.327.668A.75.75 0 0 1 8 .25Z"
+              />
+            </svg>
+          </button>
+          <button
+            class="hover:text-gray-500 py-1 px-2 my-1 mx-2 focus:outline-none"
+            title="Set as primary account"
+            type="button"
+          >
+            <svg
+              aria-label="Set as primary account"
+              class="text-yellow-500 dark:text-yellow-300"
+              fill="currentColor"
+              focusable="false"
+              height="20"
+              role="img"
+              style="display: inline-block; user-select: none; vertical-align: text-bottom; overflow: visible;"
+              viewBox="0 0 16 16"
+              width="20"
+            >
+              <path
+                d="M8 .25a.75.75 0 0 1 .673.418l1.882 3.815 4.21.612a.75.75 0 0 1 .416 1.279l-3.046 2.97.719 4.192a.751.751 0 0 1-1.088.791L8 12.347l-3.766 1.98a.75.75 0 0 1-1.088-.79l.72-4.194L.818 6.374a.75.75 0 0 1 .416-1.28l4.21-.611L7.327.668A.75.75 0 0 1 8 .25Zm0 2.445L6.615 5.5a.75.75 0 0 1-.564.41l-3.097.45 2.24 2.184a.75.75 0 0 1 .216.664l-.528 3.084 2.769-1.456a.75.75 0 0 1 .698 0l2.77 1.456-.53-3.084a.75.75 0 0 1 .216-.664l2.24-2.183-3.096-.45a.75.75 0 0 1-.564-.41L8 2.694Z"
+              />
+            </svg>
+          </button>
           <button
             class="hover:text-gray-500 py-1 px-2 my-1 mx-2 focus:outline-none"
             title="Logout octocat"
@@ -352,6 +438,49 @@ exports[`routes/Accounts.tsx General should render itself & its children 1`] = `
           </div>
         </div>
         <div>
+          <button
+            class="hover:text-gray-500 py-1 px-2 my-1 mx-2 focus:outline-none cursor-default"
+            hidden=""
+            title="Primary account"
+            type="button"
+          >
+            <svg
+              aria-label="Primary account"
+              class="text-yellow-500 dark:text-yellow-300"
+              fill="currentColor"
+              focusable="false"
+              height="20"
+              role="img"
+              style="display: inline-block; user-select: none; vertical-align: text-bottom; overflow: visible;"
+              viewBox="0 0 16 16"
+              width="20"
+            >
+              <path
+                d="M8 .25a.75.75 0 0 1 .673.418l1.882 3.815 4.21.612a.75.75 0 0 1 .416 1.279l-3.046 2.97.719 4.192a.751.751 0 0 1-1.088.791L8 12.347l-3.766 1.98a.75.75 0 0 1-1.088-.79l.72-4.194L.818 6.374a.75.75 0 0 1 .416-1.28l4.21-.611L7.327.668A.75.75 0 0 1 8 .25Z"
+              />
+            </svg>
+          </button>
+          <button
+            class="hover:text-gray-500 py-1 px-2 my-1 mx-2 focus:outline-none"
+            title="Set as primary account"
+            type="button"
+          >
+            <svg
+              aria-label="Set as primary account"
+              class="text-yellow-500 dark:text-yellow-300"
+              fill="currentColor"
+              focusable="false"
+              height="20"
+              role="img"
+              style="display: inline-block; user-select: none; vertical-align: text-bottom; overflow: visible;"
+              viewBox="0 0 16 16"
+              width="20"
+            >
+              <path
+                d="M8 .25a.75.75 0 0 1 .673.418l1.882 3.815 4.21.612a.75.75 0 0 1 .416 1.279l-3.046 2.97.719 4.192a.751.751 0 0 1-1.088.791L8 12.347l-3.766 1.98a.75.75 0 0 1-1.088-.79l.72-4.194L.818 6.374a.75.75 0 0 1 .416-1.28l4.21-.611L7.327.668A.75.75 0 0 1 8 .25Zm0 2.445L6.615 5.5a.75.75 0 0 1-.564.41l-3.097.45 2.24 2.184a.75.75 0 0 1 .216.664l-.528 3.084 2.769-1.456a.75.75 0 0 1 .698 0l2.77 1.456-.53-3.084a.75.75 0 0 1 .216-.664l2.24-2.183-3.096-.45a.75.75 0 0 1-.564-.41L8 2.694Z"
+              />
+            </svg>
+          </button>
           <button
             class="hover:text-gray-500 py-1 px-2 my-1 mx-2 focus:outline-none"
             title="Logout octocat"
diff --git a/src/routes/__snapshots__/LoginWithOAuthApp.test.tsx.snap b/src/routes/__snapshots__/LoginWithOAuthApp.test.tsx.snap
index 5d4c7ad1..c2e298b3 100644
--- a/src/routes/__snapshots__/LoginWithOAuthApp.test.tsx.snap
+++ b/src/routes/__snapshots__/LoginWithOAuthApp.test.tsx.snap
@@ -84,7 +84,7 @@ exports[`routes/LoginWithOAuthApp.tsx renders correctly 1`] = `
                 >
                   <button
                     aria-label="Create new OAuth App"
-                    class="ring-offset-background focus-visible:ring-ring inline-flex w-fit items-center justify-center whitespace-nowrap rounded text-xs font-medium transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 bg-gray-300 dark:text-black hover:opacity-90 min-w-20 h-10 px-4 py-1"
+                    class="ring-offset-background focus-visible:ring-ring inline-flex w-fit items-center justify-center whitespace-nowrap text-xs font-medium transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 bg-gray-300 dark:text-black hover:opacity-90 h-7 rounded-md px-2 py-1"
                     disabled=""
                     icon="[object Object]"
                   >
@@ -159,7 +159,7 @@ exports[`routes/LoginWithOAuthApp.tsx renders correctly 1`] = `
             >
               <button
                 aria-label="GitHub Docs"
-                class="ring-offset-background focus-visible:ring-ring inline-flex w-fit items-center justify-center whitespace-nowrap rounded text-xs font-medium transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 bg-gray-300 dark:text-black hover:opacity-90 min-w-20 h-10 px-4 py-1 mt-2"
+                class="ring-offset-background focus-visible:ring-ring inline-flex w-fit items-center justify-center whitespace-nowrap text-xs font-medium transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 bg-gray-300 dark:text-black hover:opacity-90 h-7 rounded-md px-2 py-1 mt-2"
                 icon="[object Object]"
                 name="Docs"
               >
@@ -177,6 +177,7 @@ exports[`routes/LoginWithOAuthApp.tsx renders correctly 1`] = `
                     d="M0 1.75A.75.75 0 0 1 .75 1h4.253c1.227 0 2.317.59 3 1.501A3.743 3.743 0 0 1 11.006 1h4.245a.75.75 0 0 1 .75.75v10.5a.75.75 0 0 1-.75.75h-4.507a2.25 2.25 0 0 0-1.591.659l-.622.621a.75.75 0 0 1-1.06 0l-.622-.621A2.25 2.25 0 0 0 5.258 13H.75a.75.75 0 0 1-.75-.75Zm7.251 10.324.004-5.073-.002-2.253A2.25 2.25 0 0 0 5.003 2.5H1.5v9h3.757a3.75 3.75 0 0 1 1.994.574ZM8.755 4.75l-.004 7.322a3.752 3.752 0 0 1 1.992-.572H14.5v-9h-3.495a2.25 2.25 0 0 0-2.25 2.25Z"
                   />
                 </svg>
+                Docs
               </button>
               <button
                 aria-label="Login"
@@ -200,6 +201,7 @@ exports[`routes/LoginWithOAuthApp.tsx renders correctly 1`] = `
                     d="M2 2.75C2 1.784 2.784 1 3.75 1h2.5a.75.75 0 0 1 0 1.5h-2.5a.25.25 0 0 0-.25.25v10.5c0 .138.112.25.25.25h2.5a.75.75 0 0 1 0 1.5h-2.5A1.75 1.75 0 0 1 2 13.25Zm6.56 4.5h5.69a.75.75 0 0 1 0 1.5H8.56l1.97 1.97a.749.749 0 0 1-.326 1.275.749.749 0 0 1-.734-.215L6.22 8.53a.75.75 0 0 1 0-1.06l3.25-3.25a.749.749 0 0 1 1.275.326.749.749 0 0 1-.215.734Z"
                   />
                 </svg>
+                Login
               </button>
             </div>
           </form>
@@ -287,7 +289,7 @@ exports[`routes/LoginWithOAuthApp.tsx renders correctly 1`] = `
               >
                 <button
                   aria-label="Create new OAuth App"
-                  class="ring-offset-background focus-visible:ring-ring inline-flex w-fit items-center justify-center whitespace-nowrap rounded text-xs font-medium transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 bg-gray-300 dark:text-black hover:opacity-90 min-w-20 h-10 px-4 py-1"
+                  class="ring-offset-background focus-visible:ring-ring inline-flex w-fit items-center justify-center whitespace-nowrap text-xs font-medium transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 bg-gray-300 dark:text-black hover:opacity-90 h-7 rounded-md px-2 py-1"
                   disabled=""
                   icon="[object Object]"
                 >
@@ -362,7 +364,7 @@ exports[`routes/LoginWithOAuthApp.tsx renders correctly 1`] = `
           >
             <button
               aria-label="GitHub Docs"
-              class="ring-offset-background focus-visible:ring-ring inline-flex w-fit items-center justify-center whitespace-nowrap rounded text-xs font-medium transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 bg-gray-300 dark:text-black hover:opacity-90 min-w-20 h-10 px-4 py-1 mt-2"
+              class="ring-offset-background focus-visible:ring-ring inline-flex w-fit items-center justify-center whitespace-nowrap text-xs font-medium transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 bg-gray-300 dark:text-black hover:opacity-90 h-7 rounded-md px-2 py-1 mt-2"
               icon="[object Object]"
               name="Docs"
             >
@@ -380,6 +382,7 @@ exports[`routes/LoginWithOAuthApp.tsx renders correctly 1`] = `
                   d="M0 1.75A.75.75 0 0 1 .75 1h4.253c1.227 0 2.317.59 3 1.501A3.743 3.743 0 0 1 11.006 1h4.245a.75.75 0 0 1 .75.75v10.5a.75.75 0 0 1-.75.75h-4.507a2.25 2.25 0 0 0-1.591.659l-.622.621a.75.75 0 0 1-1.06 0l-.622-.621A2.25 2.25 0 0 0 5.258 13H.75a.75.75 0 0 1-.75-.75Zm7.251 10.324.004-5.073-.002-2.253A2.25 2.25 0 0 0 5.003 2.5H1.5v9h3.757a3.75 3.75 0 0 1 1.994.574ZM8.755 4.75l-.004 7.322a3.752 3.752 0 0 1 1.992-.572H14.5v-9h-3.495a2.25 2.25 0 0 0-2.25 2.25Z"
                 />
               </svg>
+              Docs
             </button>
             <button
               aria-label="Login"
@@ -403,6 +406,7 @@ exports[`routes/LoginWithOAuthApp.tsx renders correctly 1`] = `
                   d="M2 2.75C2 1.784 2.784 1 3.75 1h2.5a.75.75 0 0 1 0 1.5h-2.5a.25.25 0 0 0-.25.25v10.5c0 .138.112.25.25.25h2.5a.75.75 0 0 1 0 1.5h-2.5A1.75 1.75 0 0 1 2 13.25Zm6.56 4.5h5.69a.75.75 0 0 1 0 1.5H8.56l1.97 1.97a.749.749 0 0 1-.326 1.275.749.749 0 0 1-.734-.215L6.22 8.53a.75.75 0 0 1 0-1.06l3.25-3.25a.749.749 0 0 1 1.275.326.749.749 0 0 1-.215.734Z"
                 />
               </svg>
+              Login
             </button>
           </div>
         </form>
diff --git a/src/routes/__snapshots__/LoginWithPersonalAccessToken.test.tsx.snap b/src/routes/__snapshots__/LoginWithPersonalAccessToken.test.tsx.snap
index dd349269..9f0f8f80 100644
--- a/src/routes/__snapshots__/LoginWithPersonalAccessToken.test.tsx.snap
+++ b/src/routes/__snapshots__/LoginWithPersonalAccessToken.test.tsx.snap
@@ -75,41 +75,21 @@ exports[`routes/LoginWithPersonalAccessToken.tsx renders correctly 1`] = `
               type="text"
               value="github.com"
             />
-            <div
-              class="mt-3 text-xs text-gray-700 dark:text-gray-200"
-            >
-              <div
-                class="mt-1 italic"
-              >
-                Change only if you are using GitHub Enterprise Server.
-              </div>
-            </div>
-          </div>
-          <div
-            class="mb-4"
-          >
-            <label
-              class="mb-2 block text-sm font-semibold tracking-wide"
-              for="token"
-            >
-              Token
-            </label>
-            <input
-              class="mb-2 block w-full appearance-none rounded border border-red-500 bg-gray-100 px-4 py-1.5 text-sm focus:bg-gray-200 focus:outline-none dark:text-gray-800"
-              id="token"
-              name="token"
-              placeholder="The 40 characters token generated on GitHub"
-              type="text"
-              value=""
-            />
             <div
               class="mt-3 text-xs text-gray-700 dark:text-gray-200"
             >
               <div>
-                <div>
+                <div
+                  class="mt-1 italic"
+                >
+                  Change only if you are using GitHub Enterprise Server.
+                </div>
+                <div
+                  class="mt-3"
+                >
                   <button
                     aria-label="Generate a PAT"
-                    class="ring-offset-background focus-visible:ring-ring inline-flex w-fit items-center justify-center whitespace-nowrap rounded text-xs font-medium transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 bg-gray-300 dark:text-black hover:opacity-90 min-w-20 h-10 px-4 py-1"
+                    class="ring-offset-background focus-visible:ring-ring inline-flex w-fit items-center justify-center whitespace-nowrap text-xs font-medium transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 bg-gray-300 dark:text-black hover:opacity-90 h-7 rounded-md px-2 py-1"
                     icon="[object Object]"
                   >
                     <svg
@@ -131,23 +111,48 @@ exports[`routes/LoginWithPersonalAccessToken.tsx renders correctly 1`] = `
                   <span
                     class="mx-1"
                   >
-                    on GitHub and paste above.
+                    on GitHub then paste your
+                     
+                    <span
+                      class="italic"
+                    >
+                      token
+                    </span>
+                     below.
                   </span>
                 </div>
                 <div
                   class="mt-1 italic"
                 >
-                  The required scopes will be selected for you.
+                  The required scopes will be automatically selected for you.
                 </div>
               </div>
             </div>
           </div>
+          <div
+            class="mb-4"
+          >
+            <label
+              class="mb-2 block text-sm font-semibold tracking-wide"
+              for="token"
+            >
+              Token
+            </label>
+            <input
+              class="mb-2 block w-full appearance-none rounded border border-red-500 bg-gray-100 px-4 py-1.5 text-sm focus:bg-gray-200 focus:outline-none dark:text-gray-800"
+              id="token"
+              name="token"
+              placeholder="The 40 characters token generated on GitHub"
+              type="text"
+              value=""
+            />
+          </div>
           <div
             class="flex items-end justify-between mt-2"
           >
             <button
               aria-label="GitHub Docs"
-              class="ring-offset-background focus-visible:ring-ring inline-flex w-fit items-center justify-center whitespace-nowrap rounded text-xs font-medium transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 bg-gray-300 dark:text-black hover:opacity-90 min-w-20 h-10 px-4 py-1"
+              class="ring-offset-background focus-visible:ring-ring inline-flex w-fit items-center justify-center whitespace-nowrap text-xs font-medium transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 bg-gray-300 dark:text-black hover:opacity-90 h-7 rounded-md px-2 py-1"
               icon="[object Object]"
             >
               <svg
@@ -265,41 +270,21 @@ exports[`routes/LoginWithPersonalAccessToken.tsx renders correctly 1`] = `
             type="text"
             value="github.com"
           />
-          <div
-            class="mt-3 text-xs text-gray-700 dark:text-gray-200"
-          >
-            <div
-              class="mt-1 italic"
-            >
-              Change only if you are using GitHub Enterprise Server.
-            </div>
-          </div>
-        </div>
-        <div
-          class="mb-4"
-        >
-          <label
-            class="mb-2 block text-sm font-semibold tracking-wide"
-            for="token"
-          >
-            Token
-          </label>
-          <input
-            class="mb-2 block w-full appearance-none rounded border border-red-500 bg-gray-100 px-4 py-1.5 text-sm focus:bg-gray-200 focus:outline-none dark:text-gray-800"
-            id="token"
-            name="token"
-            placeholder="The 40 characters token generated on GitHub"
-            type="text"
-            value=""
-          />
           <div
             class="mt-3 text-xs text-gray-700 dark:text-gray-200"
           >
             <div>
-              <div>
+              <div
+                class="mt-1 italic"
+              >
+                Change only if you are using GitHub Enterprise Server.
+              </div>
+              <div
+                class="mt-3"
+              >
                 <button
                   aria-label="Generate a PAT"
-                  class="ring-offset-background focus-visible:ring-ring inline-flex w-fit items-center justify-center whitespace-nowrap rounded text-xs font-medium transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 bg-gray-300 dark:text-black hover:opacity-90 min-w-20 h-10 px-4 py-1"
+                  class="ring-offset-background focus-visible:ring-ring inline-flex w-fit items-center justify-center whitespace-nowrap text-xs font-medium transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 bg-gray-300 dark:text-black hover:opacity-90 h-7 rounded-md px-2 py-1"
                   icon="[object Object]"
                 >
                   <svg
@@ -321,23 +306,48 @@ exports[`routes/LoginWithPersonalAccessToken.tsx renders correctly 1`] = `
                 <span
                   class="mx-1"
                 >
-                  on GitHub and paste above.
+                  on GitHub then paste your
+                   
+                  <span
+                    class="italic"
+                  >
+                    token
+                  </span>
+                   below.
                 </span>
               </div>
               <div
                 class="mt-1 italic"
               >
-                The required scopes will be selected for you.
+                The required scopes will be automatically selected for you.
               </div>
             </div>
           </div>
         </div>
+        <div
+          class="mb-4"
+        >
+          <label
+            class="mb-2 block text-sm font-semibold tracking-wide"
+            for="token"
+          >
+            Token
+          </label>
+          <input
+            class="mb-2 block w-full appearance-none rounded border border-red-500 bg-gray-100 px-4 py-1.5 text-sm focus:bg-gray-200 focus:outline-none dark:text-gray-800"
+            id="token"
+            name="token"
+            placeholder="The 40 characters token generated on GitHub"
+            type="text"
+            value=""
+          />
+        </div>
         <div
           class="flex items-end justify-between mt-2"
         >
           <button
             aria-label="GitHub Docs"
-            class="ring-offset-background focus-visible:ring-ring inline-flex w-fit items-center justify-center whitespace-nowrap rounded text-xs font-medium transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 bg-gray-300 dark:text-black hover:opacity-90 min-w-20 h-10 px-4 py-1"
+            class="ring-offset-background focus-visible:ring-ring inline-flex w-fit items-center justify-center whitespace-nowrap text-xs font-medium transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 bg-gray-300 dark:text-black hover:opacity-90 h-7 rounded-md px-2 py-1"
             icon="[object Object]"
           >
             <svg
diff --git a/src/utils/api/client.test.ts b/src/utils/api/client.test.ts
index edf0b032..7f6ac0c7 100644
--- a/src/utils/api/client.test.ts
+++ b/src/utils/api/client.test.ts
@@ -292,7 +292,7 @@ describe('utils/api/client.ts', () => {
         '123' as Token,
       );
 
-      expect(logErrorSpy).toHaveBeenCalledWith('Failed to get html url');
+      expect(logErrorSpy).toHaveBeenCalledTimes(1);
     });
   });
 });
diff --git a/src/utils/comms.test.ts b/src/utils/comms.test.ts
index 3c7402ba..e78779d1 100644
--- a/src/utils/comms.test.ts
+++ b/src/utils/comms.test.ts
@@ -72,6 +72,16 @@ describe('utils/comms.ts', () => {
     });
   });
 
+  it('should use default open preference if user settings not found', () => {
+    jest.spyOn(storage, 'loadState').mockReturnValue({ settings: null });
+
+    openExternalLink('https://www.gitify.io/' as Link);
+    expect(shell.openExternal).toHaveBeenCalledTimes(1);
+    expect(shell.openExternal).toHaveBeenCalledWith('https://www.gitify.io/', {
+      activate: true,
+    });
+  });
+
   it('should ignore opening external local links file:///', () => {
     openExternalLink('file:///Applications/SomeApp.app' as Link);
     expect(shell.openExternal).toHaveBeenCalledTimes(0);