diff --git a/.eslintrc.js b/.eslintrc.js
index 553ac75d..0a908a2e 100644
--- a/.eslintrc.js
+++ b/.eslintrc.js
@@ -5,30 +5,27 @@ module.exports = {
     es2022: true,
   },
   extends: [
-    "plugin:vue/vue3-essential",
+    "plugin:vue/vue3-recommended",
     "eslint:recommended",
     "@vue/typescript/recommended",
-    "plugin:prettier/recommended",
+    "plugin:prettier/recommended"
   ],
   // parserOptions: {
   //   ecmaVersion: 2020,
   // },
   rules: {
-    "max-len": [
-      "warn",
-      {
-        code: 120,
-        ignoreComments: true, // why does this not make it allow comment of any length?
-        ignorePattern: '^\\s*class="[^"]*"$',
-        ignoreStrings: true,
-        ignoreTemplateLiterals: true,
-        ignoreTrailingComments: true,
-        ignoreUrls: true,
-      },
-    ],
-    "no-console": process.env.NODE_ENV === "production" ? "warn" : "off",
-    "no-debugger": process.env.NODE_ENV === "production" ? "warn" : "off",
-    // "prettier/prettier": ["warn", { printWidth: 120 }], // removes errors but adds thousands of warnings
-    "@typescript-eslint/no-unnecessary-type-constraint": "off",
+    "max-len": ["warn", {
+      code: 100,
+      ignoreComments: true,
+      ignorePattern: '^\\s*class="[^"]*"$',
+      ignoreStrings: true,
+      ignoreTemplateLiterals: true,
+      ignoreUrls: true,
+    }],
+    "no-console": process.env.NODE_ENV === "production" ? "error" : "warn",
+    "no-debugger": process.env.NODE_ENV === "production" ? "error" : "warn",
+    "@typescript-eslint/no-explicit-any": "warn",
+    "@typescript-eslint/explicit-function-return-type": "off",
+    "@typescript-eslint/no-unnecessary-type-constraint": "off"
   },
 };
diff --git a/package-lock.json b/package-lock.json
index 1f045340..12cc0db3 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -69,7 +69,6 @@
         "simple-vue-camera": "^1.1.3",
         "three": "^0.156.1",
         "ua-parser-js": "^1.0.37",
-        "util": "^0.12.5",
         "vue": "^3.5.13",
         "vue-axios": "^3.5.2",
         "vue-facing-decorator": "^3.0.4",
@@ -104,8 +103,10 @@
         "postcss": "^8.4.38",
         "prettier": "^3.2.5",
         "rimraf": "^6.0.1",
+        "stream-browserify": "^3.0.0",
         "tailwindcss": "^3.4.1",
         "typescript": "~5.2.2",
+        "util": "^0.12.5",
         "vite": "^5.2.0",
         "vite-plugin-pwa": "^0.19.8"
       }
@@ -11454,6 +11455,7 @@
       "version": "1.0.7",
       "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.7.tgz",
       "integrity": "sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==",
+      "dev": true,
       "license": "MIT",
       "dependencies": {
         "possible-typed-array-names": "^1.0.0"
@@ -12344,6 +12346,7 @@
       "version": "1.0.8",
       "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.8.tgz",
       "integrity": "sha512-oKlSFMcMwpUg2ednkhQ454wfWiU/ul3CkJe/PEHcTKuiX6RpbehUiFMXu13HalGZxfUwCQzZG747YXBn1im9ww==",
+      "dev": true,
       "license": "MIT",
       "dependencies": {
         "call-bind-apply-helpers": "^1.0.0",
@@ -12375,6 +12378,7 @@
       "version": "1.0.3",
       "resolved": "https://registry.npmjs.org/call-bound/-/call-bound-1.0.3.tgz",
       "integrity": "sha512-YTd+6wGlNlPxSuri7Y6X8tY2dmm12UMH66RpKMhiX6rsk5wXXnYgbUcOt8kiS31/AjfoTOvCsE+w8nZQLQnzHA==",
+      "dev": true,
       "license": "MIT",
       "dependencies": {
         "call-bind-apply-helpers": "^1.0.1",
@@ -13803,6 +13807,7 @@
       "version": "1.1.4",
       "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz",
       "integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==",
+      "dev": true,
       "license": "MIT",
       "dependencies": {
         "es-define-property": "^1.0.0",
@@ -16122,6 +16127,7 @@
       "version": "0.3.5",
       "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.5.tgz",
       "integrity": "sha512-dKx12eRCVIzqCxFGplyFKJMPvLEWgmNtUrpTiJIR5u97zEhRG8ySrtboPHZXx7daLxQVrl643cTzbab2tkQjxg==",
+      "dev": true,
       "license": "MIT",
       "dependencies": {
         "is-callable": "^1.2.7"
@@ -16720,6 +16726,7 @@
       "version": "1.0.2",
       "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz",
       "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==",
+      "dev": true,
       "license": "MIT",
       "dependencies": {
         "es-define-property": "^1.0.0"
@@ -17227,6 +17234,7 @@
       "version": "1.2.0",
       "resolved": "https://registry.npmjs.org/is-arguments/-/is-arguments-1.2.0.tgz",
       "integrity": "sha512-7bVbi0huj/wrIAOzb8U1aszg9kdi3KN/CyU19CTI7tAoZYEZoL9yCDXpbXN+uPsuWnP02cyug1gleqq+TU+YCA==",
+      "dev": true,
       "license": "MIT",
       "dependencies": {
         "call-bound": "^1.0.2",
@@ -17343,6 +17351,7 @@
       "version": "1.2.7",
       "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz",
       "integrity": "sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==",
+      "dev": true,
       "license": "MIT",
       "engines": {
         "node": ">= 0.4"
@@ -17480,6 +17489,7 @@
       "version": "1.1.0",
       "resolved": "https://registry.npmjs.org/is-generator-function/-/is-generator-function-1.1.0.tgz",
       "integrity": "sha512-nPUB5km40q9e8UfN/Zc24eLlzdSf9OfKByBw9CIdw4H1giPMeA0OIJvbchsCu4npfI2QcMVBsGEBHKZ7wLTWmQ==",
+      "dev": true,
       "license": "MIT",
       "dependencies": {
         "call-bound": "^1.0.3",
@@ -17630,6 +17640,7 @@
       "version": "1.2.1",
       "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.2.1.tgz",
       "integrity": "sha512-MjYsKHO5O7mCsmRGxWcLWheFqN9DJ/2TmngvjKXihe6efViPqc274+Fx/4fYj/r03+ESvBdTXK0V6tA3rgez1g==",
+      "dev": true,
       "license": "MIT",
       "dependencies": {
         "call-bound": "^1.0.2",
@@ -17733,6 +17744,7 @@
       "version": "1.1.15",
       "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.15.tgz",
       "integrity": "sha512-p3EcsicXjit7SaskXHs1hA91QxgTw46Fv6EFKKGS5DRFLD8yKnohjF3hxoju94b/OcMZoQukzpPpBE9uLVKzgQ==",
+      "dev": true,
       "license": "MIT",
       "dependencies": {
         "which-typed-array": "^1.1.16"
@@ -21810,6 +21822,7 @@
       "version": "1.1.0",
       "resolved": "https://registry.npmjs.org/possible-typed-array-names/-/possible-typed-array-names-1.1.0.tgz",
       "integrity": "sha512-/+5VFTchJDoVj3bhoqi6UeymcD00DAwb1nJwamzPvHEszJ4FpF6SNNbUbOS8yI56qHzdV8eK0qEfOSiodkTdxg==",
+      "dev": true,
       "license": "MIT",
       "engines": {
         "node": ">= 0.4"
@@ -23684,6 +23697,7 @@
       "version": "1.1.0",
       "resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.1.0.tgz",
       "integrity": "sha512-x/+Cz4YrimQxQccJf5mKEbIa1NzeCRNI5Ecl/ekmlYaampdNLPalVyIcCZNNH3MvmqBugV5TMYZXv0ljslUlaw==",
+      "dev": true,
       "license": "MIT",
       "dependencies": {
         "call-bound": "^1.0.2",
@@ -24071,6 +24085,7 @@
       "version": "1.2.2",
       "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz",
       "integrity": "sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==",
+      "dev": true,
       "license": "MIT",
       "dependencies": {
         "define-data-property": "^1.1.4",
@@ -24619,6 +24634,32 @@
       "license": "MIT",
       "optional": true
     },
+    "node_modules/stream-browserify": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/stream-browserify/-/stream-browserify-3.0.0.tgz",
+      "integrity": "sha512-H73RAHsVBapbim0tU2JwwOiXUj+fikfiaoYAKHF3VJfA0pe2BCzkhAHBlLG6REzE+2WNZcxOXjK7lkso+9euLA==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "inherits": "~2.0.4",
+        "readable-stream": "^3.5.0"
+      }
+    },
+    "node_modules/stream-browserify/node_modules/readable-stream": {
+      "version": "3.6.2",
+      "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz",
+      "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "inherits": "^2.0.3",
+        "string_decoder": "^1.1.1",
+        "util-deprecate": "^1.0.1"
+      },
+      "engines": {
+        "node": ">= 6"
+      }
+    },
     "node_modules/stream-buffers": {
       "version": "2.2.0",
       "resolved": "https://registry.npmjs.org/stream-buffers/-/stream-buffers-2.2.0.tgz",
@@ -26196,6 +26237,7 @@
       "version": "0.12.5",
       "resolved": "https://registry.npmjs.org/util/-/util-0.12.5.tgz",
       "integrity": "sha512-kZf/K6hEIrWHI6XqOFUiiMa+79wE/D8Q+NCNAWclkyg3b4d2k7s0QGepNjiABc+aR3N1PAyHL7p6UcLY6LmrnA==",
+      "dev": true,
       "license": "MIT",
       "dependencies": {
         "inherits": "^2.0.3",
@@ -26805,6 +26847,7 @@
       "version": "1.1.18",
       "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.18.tgz",
       "integrity": "sha512-qEcY+KJYlWyLH9vNbsr6/5j59AXk5ni5aakf8ldzBvGde6Iz4sxZGkJyWSAueTG7QhOvNRYb1lDdFmL5Td0QKA==",
+      "dev": true,
       "license": "MIT",
       "dependencies": {
         "available-typed-arrays": "^1.0.7",
diff --git a/package.json b/package.json
index eff6a2ad..3e7d96f0 100644
--- a/package.json
+++ b/package.json
@@ -91,9 +91,9 @@
     "reflect-metadata": "^0.1.14",
     "register-service-worker": "^1.7.2",
     "simple-vue-camera": "^1.1.3",
+    "stream-browserify": "^3.0.0",
     "three": "^0.156.1",
     "ua-parser-js": "^1.0.37",
-    "util": "^0.12.5",
     "vue": "^3.5.13",
     "vue-axios": "^3.5.2",
     "vue-facing-decorator": "^3.0.4",
diff --git a/src/App.vue b/src/App.vue
index df60ac78..5d7f9c83 100644
--- a/src/App.vue
+++ b/src/App.vue
@@ -51,8 +51,8 @@
               <p class="text-sm">{{ truncateLongWords(notification.text) }}</p>
 
               <button
-                @click="close(notification.id)"
                 class="absolute top-2 right-2 px-0.5 py-0 rounded-full bg-slate-200 text-slate-600"
+                @click="close(notification.id)"
               >
                 <font-awesome icon="xmark" class="fa-fw"></font-awesome>
               </button>
@@ -77,8 +77,8 @@
               <p class="text-sm">{{ truncateLongWords(notification.text) }}</p>
 
               <button
-                @click="close(notification.id)"
                 class="absolute top-2 right-2 px-0.5 py-0 rounded-full bg-emerald-200 text-emerald-600"
+                @click="close(notification.id)"
               >
                 <font-awesome icon="xmark" class="fa-fw"></font-awesome>
               </button>
@@ -103,8 +103,8 @@
               <p class="text-sm">{{ truncateLongWords(notification.text) }}</p>
 
               <button
-                @click="close(notification.id)"
                 class="absolute top-2 right-2 px-0.5 py-0 rounded-full bg-amber-200 text-amber-600"
+                @click="close(notification.id)"
               >
                 <font-awesome icon="xmark" class="fa-fw"></font-awesome>
               </button>
@@ -129,8 +129,8 @@
               <p class="text-sm">{{ truncateLongWords(notification.text) }}</p>
 
               <button
-                @click="close(notification.id)"
                 class="absolute top-2 right-2 px-0.5 py-0 rounded-full bg-rose-200 text-rose-600"
+                @click="close(notification.id)"
               >
                 <font-awesome icon="xmark" class="fa-fw"></font-awesome>
               </button>
@@ -186,11 +186,11 @@
 
                 <button
                   v-if="notification.onYes"
+                  class="block w-full text-center text-md font-bold uppercase bg-blue-600 text-white px-2 py-2 rounded-md mb-2"
                   @click="
                     notification.onYes();
                     close(notification.id);
                   "
-                  class="block w-full text-center text-md font-bold uppercase bg-blue-600 text-white px-2 py-2 rounded-md mb-2"
                 >
                   Yes{{
                     notification.yesText ? ", " + notification.yesText : ""
@@ -199,12 +199,12 @@
 
                 <button
                   v-if="notification.onNo"
+                  class="block w-full text-center text-md font-bold uppercase bg-yellow-600 text-white px-2 py-2 rounded-md mb-2"
                   @click="
                     notification.onNo(stopAsking);
                     close(notification.id);
                     stopAsking = false; // reset value
                   "
-                  class="block w-full text-center text-md font-bold uppercase bg-yellow-600 text-white px-2 py-2 rounded-md mb-2"
                 >
                   No{{ notification.noText ? ", " + notification.noText : "" }}
                 </button>
@@ -221,8 +221,8 @@
                   <div class="relative ml-2">
                     <!-- input -->
                     <input
-                      type="checkbox"
                       v-model="stopAsking"
+                      type="checkbox"
                       name="stopAsking"
                       class="sr-only"
                     />
@@ -236,6 +236,7 @@
                 </label>
 
                 <button
+                  class="block w-full text-center text-md font-bold uppercase bg-slate-600 text-white px-2 py-2 rounded-md"
                   @click="
                     notification.onCancel
                       ? notification.onCancel(stopAsking)
@@ -243,7 +244,6 @@
                     close(notification.id);
                     stopAsking = false; // reset value for next time they open this modal
                   "
-                  class="block w-full text-center text-md font-bold uppercase bg-slate-600 text-white px-2 py-2 rounded-md"
                 >
                   {{ notification.onYes ? "Cancel" : "Close" }}
                 </button>
@@ -282,8 +282,8 @@
                   Until I turn it back on
                 </button>
                 <button
-                  @click="close(notification.id)"
                   class="block w-full text-center text-md font-bold uppercase bg-slate-600 text-white px-2 py-2 rounded-md"
+                  @click="close(notification.id)"
                 >
                   Cancel
                 </button>
@@ -304,17 +304,17 @@
                 </p>
 
                 <button
+                  class="block w-full text-center text-md font-bold uppercase bg-rose-600 text-white px-2 py-2 rounded-md mb-2"
                   @click="
                     close(notification.id);
                     turnOffNotifications(notification);
                   "
-                  class="block w-full text-center text-md font-bold uppercase bg-rose-600 text-white px-2 py-2 rounded-md mb-2"
                 >
                   Turn Off Notification
                 </button>
                 <button
-                  @click="close(notification.id)"
                   class="block w-full text-center text-md font-bold uppercase bg-slate-600 text-white px-2 py-2 rounded-md"
+                  @click="close(notification.id)"
                 >
                   Leave it On
                 </button>
@@ -327,8 +327,6 @@
   </NotificationGroup>
 </template>
 
-<style></style>
-
 <script lang="ts">
 import { Vue, Component } from "vue-facing-decorator";
 import { logConsoleAndDb, retrieveSettingsForActiveAccount } from "./db/index";
@@ -538,3 +536,5 @@ export default class App extends Vue {
   }
 }
 </script>
+
+<style></style>
diff --git a/src/components/ChoiceButtonDialog.vue b/src/components/ChoiceButtonDialog.vue
index 5a7ce958..241a1b73 100644
--- a/src/components/ChoiceButtonDialog.vue
+++ b/src/components/ChoiceButtonDialog.vue
@@ -29,29 +29,29 @@
                 <p class="text-sm mb-2">{{ text }}</p>
 
                 <button
-                  @click="handleOption1(close)"
                   class="block w-full text-center text-md font-bold capitalize bg-blue-800 text-white px-2 py-2 rounded-md mb-2"
+                  @click="handleOption1(close)"
                 >
                   {{ option1Text }}
                 </button>
 
                 <button
-                  @click="handleOption2(close)"
                   class="block w-full text-center text-md font-bold capitalize bg-blue-700 text-white px-2 py-2 rounded-md mb-2"
+                  @click="handleOption2(close)"
                 >
                   {{ option2Text }}
                 </button>
 
                 <button
-                  @click="handleOption3(close)"
                   class="block w-full text-center text-md font-bold capitalize bg-blue-600 text-white px-2 py-2 rounded-md mb-2"
+                  @click="handleOption3(close)"
                 >
                   {{ option3Text }}
                 </button>
 
                 <button
-                  @click="handleCancel(close)"
                   class="block w-full text-center text-md font-bold capitalize bg-slate-600 text-white px-2 py-2 rounded-md"
+                  @click="handleCancel(close)"
                 >
                   Cancel
                 </button>
diff --git a/src/components/ContactNameDialog.vue b/src/components/ContactNameDialog.vue
index 7a9c4ecf..1198e2f7 100644
--- a/src/components/ContactNameDialog.vue
+++ b/src/components/ContactNameDialog.vue
@@ -6,10 +6,10 @@
       {{ message }}
       Note that their name is only stored on this device.
       <input
+        v-model="newText"
         type="text"
         placeholder="Name"
         class="block w-full rounded border border-slate-400 mb-4 px-3 py-2"
-        v-model="newText"
       />
 
       <div class="mt-8">
diff --git a/src/components/EntityIcon.vue b/src/components/EntityIcon.vue
index 967a08ed..1ea0a903 100644
--- a/src/components/EntityIcon.vue
+++ b/src/components/EntityIcon.vue
@@ -1,5 +1,5 @@
 <template>
-  <div v-html="generateIcon()" class="w-fit"></div>
+  <div class="w-fit" v-html="generateIcon()"></div>
 </template>
 <script lang="ts">
 import { createAvatar, StyleOptions } from "@dicebear/core";
diff --git a/src/components/FeedFilters.vue b/src/components/FeedFilters.vue
index 7762edfa..6ca4c55f 100644
--- a/src/components/FeedFilters.vue
+++ b/src/components/FeedFilters.vue
@@ -16,8 +16,8 @@
           <div class="relative ml-2">
             <!-- input -->
             <input
-              type="checkbox"
               v-model="hasVisibleDid"
+              type="checkbox"
               name="toggleFilterFromMyContacts"
               class="sr-only"
             />
@@ -46,8 +46,8 @@
           <div v-if="hasSearchBox" class="relative ml-2">
             <!-- input -->
             <input
-              type="checkbox"
               v-model="isNearby"
+              type="checkbox"
               name="toggleFilterNearby"
               class="sr-only"
             />
diff --git a/src/components/GiftedDialog.vue b/src/components/GiftedDialog.vue
index fedbb50c..c9064762 100644
--- a/src/components/GiftedDialog.vue
+++ b/src/components/GiftedDialog.vue
@@ -5,10 +5,10 @@
         {{ customTitle }}
       </h1>
       <input
+        v-model="description"
         type="text"
         class="block w-full rounded border border-slate-400 mb-2 px-3 py-2"
         :placeholder="prompt || 'What was given?'"
-        v-model="description"
       />
       <div class="flex flex-row justify-center">
         <span
@@ -25,9 +25,9 @@
         </div>
         <input
           id="inputGivenAmount"
+          v-model="amountInput"
           type="number"
           class="border border-r-0 border-slate-400 px-2 py-2 text-center w-20"
-          v-model="amountInput"
         />
         <div
           class="rounded-r border border-slate-400 bg-slate-200 px-4 py-2"
diff --git a/src/components/HiddenDidDialog.vue b/src/components/HiddenDidDialog.vue
index 847e1bbd..4356392c 100644
--- a/src/components/HiddenDidDialog.vue
+++ b/src/components/HiddenDidDialog.vue
@@ -7,7 +7,7 @@
       <!-- Header -->
       <div class="flex justify-between items-center mb-4">
         <h2 class="text-xl font-bold capitalize">{{ roleName }} Details</h2>
-        <button @click="close" class="text-gray-500 hover:text-gray-700">
+        <button class="text-gray-500 hover:text-gray-700" @click="close">
           <font-awesome icon="times" />
         </button>
       </div>
@@ -69,7 +69,7 @@
         <div class="mt-4">
           <span v-if="canShare">
             If you'd like an introduction,
-            <a @click="onClickShareClaim()" class="text-blue-500"
+            <a class="text-blue-500" @click="onClickShareClaim()"
               >click here to share the information with them and ask if they'll
               tell you more about the {{ roleName }}.</a
             >
@@ -77,8 +77,8 @@
           <span v-else>
             If you'd like an introduction,
             <a
-              @click="copyToClipboard('A link to this page', windowLocation)"
               class="text-blue-500"
+              @click="copyToClipboard('A link to this page', windowLocation)"
               >click here to copy this page, paste it into a message, and ask if
               they'll tell you more about the {{ roleName }}.</a
             >
@@ -89,8 +89,8 @@
       <!-- Footer -->
       <div class="flex justify-end">
         <button
-          @click="close"
           class="bg-blue-500 text-white px-4 py-2 rounded hover:bg-blue-600"
+          @click="close"
         >
           Close
         </button>
diff --git a/src/components/ImageMethodDialog.vue b/src/components/ImageMethodDialog.vue
index d4e11457..8a3faaa2 100644
--- a/src/components/ImageMethodDialog.vue
+++ b/src/components/ImageMethodDialog.vue
@@ -31,7 +31,7 @@
           <div class="mt-4">
             <span class="mt-2">
               ... or paste a URL:
-              <input type="text" v-model="imageUrl" class="border-2" />
+              <input v-model="imageUrl" type="text" class="border-2" />
             </span>
             <span class="ml-2">
               <font-awesome
diff --git a/src/components/ImageViewer.vue b/src/components/ImageViewer.vue
index 635660ce..8b58a274 100644
--- a/src/components/ImageViewer.vue
+++ b/src/components/ImageViewer.vue
@@ -27,8 +27,8 @@
             <img
               :src="imageUrl"
               class="max-h-[calc(100vh-5rem)] w-full h-full object-contain"
-              @click.stop
               alt="expanded shared content"
+              @click.stop
             />
           </div>
         </div>
diff --git a/src/components/InviteDialog.vue b/src/components/InviteDialog.vue
index a7b04506..73d95e27 100644
--- a/src/components/InviteDialog.vue
+++ b/src/components/InviteDialog.vue
@@ -8,18 +8,18 @@
       If you want to store your own way, the invitation ID is:
       {{ inviteIdentifier }}
       <input
+        v-model="text"
         type="text"
         placeholder="Notes"
         class="block w-full rounded border border-slate-400 mb-4 px-3 py-2"
-        v-model="text"
       />
 
       <!-- Add date selection element -->
       Expiration
       <input
+        v-model="expiresAt"
         type="date"
         class="block rounded border border-slate-400 mb-4 px-3 py-2"
-        v-model="expiresAt"
       />
 
       <div class="mt-8">
diff --git a/src/components/MembersList.vue b/src/components/MembersList.vue
index c63cf2b4..f8256466 100644
--- a/src/components/MembersList.vue
+++ b/src/components/MembersList.vue
@@ -63,9 +63,9 @@
       <div class="flex justify-center">
         <!-- always have at least one refresh button even without members in case the organizer changes the password -->
         <button
-          @click="fetchMembers"
           class="w-8 h-8 flex items-center justify-center rounded-full bg-blue-100 text-blue-600 hover:bg-blue-200 hover:text-blue-800 transition-colors"
           title="Refresh members list"
+          @click="fetchMembers"
         >
           <font-awesome icon="rotate" :class="{ 'fa-spin': isLoading }" />
         </button>
@@ -83,22 +83,22 @@
               class="flex justify-end"
             >
               <button
-                @click="addAsContact(member)"
                 class="ml-2 w-8 h-8 flex items-center justify-center rounded-full bg-green-100 text-green-600 hover:bg-green-200 hover:text-green-800 transition-colors"
                 title="Add as contact"
+                @click="addAsContact(member)"
               >
                 <font-awesome icon="circle-user" class="text-xl" />
               </button>
             </div>
             <button
               v-if="member.did !== activeDid"
+              class="ml-2 mb-2 w-6 h-6 flex items-center justify-center rounded-full bg-slate-100 text-slate-500 hover:bg-slate-200 hover:text-slate-800 transition-colors"
+              title="Contact info"
               @click="
                 informAboutAddingContact(
                   getContactFor(member.did) !== undefined,
                 )
               "
-              class="ml-2 mb-2 w-6 h-6 flex items-center justify-center rounded-full bg-slate-100 text-slate-500 hover:bg-slate-200 hover:text-slate-800 transition-colors"
-              title="Contact info"
             >
               <font-awesome icon="circle-info" class="text-base" />
             </button>
@@ -111,11 +111,11 @@
               class="flex items-center"
             >
               <button
-                @click="checkWhetherContactBeforeAdmitting(member)"
                 class="mr-2 w-6 h-6 flex items-center justify-center rounded-full bg-blue-100 text-blue-600 hover:bg-blue-200 hover:text-blue-800 transition-colors"
                 :title="
                   member.member.admitted ? 'Remove member' : 'Admit member'
                 "
+                @click="checkWhetherContactBeforeAdmitting(member)"
               >
                 <font-awesome
                   :icon="member.member.admitted ? 'minus' : 'plus'"
@@ -123,9 +123,9 @@
                 />
               </button>
               <button
-                @click="informAboutAdmission()"
                 class="mr-2 mb-2 w-6 h-6 flex items-center justify-center rounded-full bg-slate-100 text-slate-500 hover:bg-slate-200 hover:text-slate-800 transition-colors"
                 title="Admission info"
+                @click="informAboutAdmission()"
               >
                 <font-awesome icon="circle-info" class="text-base" />
               </button>
@@ -138,9 +138,9 @@
       </div>
       <div v-if="membersToShow().length > 0" class="flex justify-center mt-4">
         <button
-          @click="fetchMembers"
           class="w-8 h-8 flex items-center justify-center rounded-full bg-blue-100 text-blue-600 hover:bg-blue-200 hover:text-blue-800 transition-colors"
           title="Refresh members list"
+          @click="fetchMembers"
         >
           <font-awesome icon="rotate" :class="{ 'fa-spin': isLoading }" />
         </button>
diff --git a/src/components/OfferDialog.vue b/src/components/OfferDialog.vue
index 5f16ce3f..d1b0b782 100644
--- a/src/components/OfferDialog.vue
+++ b/src/components/OfferDialog.vue
@@ -3,11 +3,11 @@
     <div class="dialog">
       <h1 class="text-xl font-bold text-center mb-4">Offer Help</h1>
       <input
+        v-model="description"
         type="text"
         data-testId="inputDescription"
         class="block w-full rounded border border-slate-400 mb-2 px-3 py-2"
         placeholder="Description of what is offered"
-        v-model="description"
       />
       <div class="flex flex-row mt-2">
         <span
@@ -17,17 +17,17 @@
           {{ libsUtil.UNIT_SHORT[amountUnitCode] }}
         </span>
         <div
+          v-if="amountInput !== '0'"
           class="border border-r-0 border-slate-400 bg-slate-200 px-4 py-2"
           @click="decrement()"
-          v-if="amountInput !== '0'"
         >
           <font-awesome icon="chevron-left" />
         </div>
         <input
+          v-model="amountInput"
           data-testId="inputOfferAmount"
           type="number"
           class="w-full border border-r-0 border-slate-400 px-2 py-2 text-center"
-          v-model="amountInput"
         />
         <div
           class="rounded-r border border-slate-400 bg-slate-200 px-4 py-2"
diff --git a/src/components/PhotoDialog.vue b/src/components/PhotoDialog.vue
index cd18738c..9e38e267 100644
--- a/src/components/PhotoDialog.vue
+++ b/src/components/PhotoDialog.vue
@@ -28,7 +28,7 @@
       <div v-else-if="blob">
         <div v-if="crop">
           <VuePictureCropper
-            :boxStyle="{
+            :box-style="{
               backgroundColor: '#f8f8f8',
               margin: 'auto',
             }"
@@ -56,8 +56,8 @@
         </div>
         <div class="absolute bottom-[1rem] left-[1rem] px-2 py-1">
           <button
-            @click="uploadImage"
             class="bg-gradient-to-b from-blue-400 to-blue-700 shadow-[inset_0_-1px_0_0_rgba(0,0,0,0.5)] text-white py-1 px-2 rounded-md"
+            @click="uploadImage"
           >
             <span>Upload</span>
           </button>
@@ -67,8 +67,8 @@
           class="absolute bottom-[1rem] right-[1rem] px-2 py-1"
         >
           <button
-            @click="retryImage"
             class="bg-gradient-to-b from-slate-400 to-slate-700 shadow-[inset_0_-1px_0_0_rgba(0,0,0,0.5)] text-white py-1 px-2 rounded-md"
+            @click="retryImage"
           >
             <span>Retry</span>
           </button>
@@ -81,17 +81,17 @@
           :resolution="{ width: 375, height: 812 }"
         -->
         <camera
-          facingMode="environment"
-          autoplay
           ref="camera"
+          facing-mode="environment"
+          autoplay
           @started="cameraStarted()"
         >
           <div
             class="absolute portrait:bottom-0 portrait:left-0 portrait:right-0 portrait:pb-2 landscape:right-0 landscape:top-0 landscape:bottom-0 landscape:pr-4 flex landscape:flex-row justify-center items-center"
           >
             <button
-              @click="takeImage()"
               class="bg-blue-500 hover:bg-blue-700 text-white font-bold p-3 rounded-full text-2xl leading-none"
+              @click="takeImage()"
             >
               <font-awesome icon="camera" class="w-[1em]"></font-awesome>
             </button>
@@ -100,16 +100,16 @@
             class="absolute portrait:bottom-2 portrait:right-16 landscape:right-0 landscape:bottom-16 landscape:pr-4 flex justify-center items-center"
           >
             <button
-              @click="swapMirrorClass()"
               class="bg-blue-500 hover:bg-blue-700 text-white font-bold p-3 rounded-full text-2xl leading-none"
+              @click="swapMirrorClass()"
             >
               <font-awesome icon="left-right" class="w-[1em]"></font-awesome>
             </button>
           </div>
           <div v-if="numDevices > 1" class="absolute bottom-2 right-4">
             <button
-              @click="switchCamera()"
               class="bg-blue-500 hover:bg-blue-700 text-white font-bold p-3 rounded-full text-2xl leading-none"
+              @click="switchCamera()"
             >
               <font-awesome icon="rotate" class="w-[1em]"></font-awesome>
             </button>
diff --git a/src/components/ProjectIcon.vue b/src/components/ProjectIcon.vue
index 093850d5..ba7d853a 100644
--- a/src/components/ProjectIcon.vue
+++ b/src/components/ProjectIcon.vue
@@ -5,12 +5,12 @@
     target="_blank"
     class="h-full w-full object-contain"
   >
-    <div v-html="generateIdenticon()" class="h-full w-full object-contain" />
+    <div class="h-full w-full object-contain" v-html="generateIdenticon()" />
   </a>
   <div
     v-else
-    v-html="generateIdenticon()"
     class="h-full w-full object-contain"
+    v-html="generateIdenticon()"
   />
 </template>
 <script lang="ts">
diff --git a/src/components/PushNotificationPermission.vue b/src/components/PushNotificationPermission.vue
index 90e8b9b0..0b73bb78 100644
--- a/src/components/PushNotificationPermission.vue
+++ b/src/components/PushNotificationPermission.vue
@@ -54,16 +54,16 @@
               <span class="flex flex-row justify-center">
                 <span class="mt-2">... at: </span>
                 <input
+                  v-model="hourInput"
                   type="number"
-                  @change="checkHourInput"
                   class="rounded-l border border-r-0 border-slate-400 ml-2 mt-2 px-2 py-2 text-center w-20"
-                  v-model="hourInput"
+                  @change="checkHourInput"
                 />
                 <input
+                  v-model="minuteInput"
                   type="number"
-                  @change="checkMinuteInput"
                   class="border border-slate-400 mt-2 px-2 py-2 text-center w-20"
-                  v-model="minuteInput"
+                  @change="checkMinuteInput"
                 />
                 <span
                   class="rounded-r border border-slate-400 bg-slate-200 text-center text-blue-500 mt-2 px-2 py-2 w-20"
@@ -88,8 +88,8 @@
           </div>
 
           <button
-            @click="close()"
             class="block w-full text-center text-md font-bold uppercase bg-slate-600 text-white mt-4 px-2 py-2 rounded-md"
+            @click="close()"
           >
             No, Not Now
           </button>
diff --git a/src/components/UserNameDialog.vue b/src/components/UserNameDialog.vue
index 0b3492bd..c7dddddb 100644
--- a/src/components/UserNameDialog.vue
+++ b/src/components/UserNameDialog.vue
@@ -6,10 +6,10 @@
 
       {{ sharingExplanation }}
       <input
+        v-model="givenName"
         type="text"
         placeholder="Name"
         class="block w-full rounded border border-slate-400 mb-4 px-3 py-2"
-        v-model="givenName"
       />
 
       <div class="mt-8">
diff --git a/src/main.common.ts b/src/main.common.ts
index a433b55f..3eab4ede 100644
--- a/src/main.common.ts
+++ b/src/main.common.ts
@@ -37,7 +37,7 @@ export function initializeApp() {
   const app = createApp(App);
   console.log("[App Init] Vue app created");
 
-  app.component("font-awesome", FontAwesomeIcon).component("camera", Camera);
+  app.component("FontAwesome", FontAwesomeIcon).component("camera", Camera);
   console.log("[App Init] Components registered");
 
   const pinia = createPinia();
diff --git a/src/views/AccountViewView.vue b/src/views/AccountViewView.vue
index 3fae7c97..9ec26322 100644
--- a/src/views/AccountViewView.vue
+++ b/src/views/AccountViewView.vue
@@ -56,13 +56,13 @@
         class="block w-full text-center text-md bg-amber-200 border border-dashed border-slate-400 px-1.5 py-2 rounded-md mb-2"
       >
         <button
+          class="inline-block text-md uppercase bg-gradient-to-b from-blue-400 to-blue-700 shadow-[inset_0_-1px_0_0_rgba(0,0,0,0.5)] text-white px-4 py-2 rounded-md"
           @click="
             () =>
-              (this.$refs.userNameDialog as UserNameDialog).open(
-                (name) => (this.givenName = name),
+              ($refs.userNameDialog as UserNameDialog).open(
+                (name) => (givenName = name),
               )
           "
-          class="inline-block text-md uppercase bg-gradient-to-b from-blue-400 to-blue-700 shadow-[inset_0_-1px_0_0_rgba(0,0,0,0.5)] text-white px-4 py-2 rounded-md"
         >
           Set Your Name
         </button>
@@ -72,14 +72,14 @@
         <span v-if="profileImageUrl" class="flex justify-between">
           <EntityIcon
             :icon-size="96"
-            :profileImageUrl="profileImageUrl"
+            :profile-image-url="profileImageUrl"
             class="inline-block align-text-bottom border border-slate-300 rounded"
             @click="showLargeIdenticonUrl = profileImageUrl"
           />
           <font-awesome
             icon="trash-can"
-            @click="confirmDeleteImage"
             class="text-red-500 fa-fw ml-8 mt-8 w-12 h-12"
+            @click="confirmDeleteImage"
           />
         </span>
         <div v-else class="text-center">
@@ -104,8 +104,8 @@
         </div>
         <div class="flex justify-center">
           <EntityIcon
-            :entityId="activeDid"
-            :iconSize="64"
+            :entity-id="activeDid"
+            :icon-size="64"
             class="inline-block align-middle border border-slate-300 rounded-md mr-1"
             @click="showLargeIdenticonId = activeDid"
           />
@@ -119,9 +119,9 @@
           class="absolute inset-0 h-screen flex flex-col items-center justify-center bg-slate-900/50"
         >
           <EntityIcon
-            :entityId="showLargeIdenticonId"
-            :iconSize="512"
-            :profileImageUrl="showLargeIdenticonUrl"
+            :entity-id="showLargeIdenticonId"
+            :icon-size="512"
+            :profile-image-url="showLargeIdenticonUrl"
             class="flex w-11/12 max-w-sm mx-auto mb-3 overflow-hidden bg-white rounded-lg shadow-lg"
             @click="
               showLargeIdenticonId = undefined;
@@ -138,10 +138,10 @@
       >
         <code class="truncate">{{ activeDid }}</code>
         <button
+          class="ml-2"
           @click="
             doCopyTwoSecRedo(activeDid, () => (showDidCopy = !showDidCopy))
           "
-          class="ml-2"
         >
           <font-awesome icon="copy" class="text-slate-400 fa-fw"></font-awesome>
         </button>
@@ -200,7 +200,7 @@
           @click="showReminderNotificationChoice()"
         >
           <!-- input -->
-          <input type="checkbox" v-model="notifyingReminder" class="sr-only" />
+          <input v-model="notifyingReminder" type="checkbox" class="sr-only" />
           <!-- line -->
           <div class="block bg-slate-500 w-14 h-8 rounded-full"></div>
           <!-- dot -->
@@ -230,8 +230,8 @@
         >
           <!-- input -->
           <input
-            type="checkbox"
             v-model="notifyingNewActivity"
+            type="checkbox"
             class="sr-only"
           />
           <!-- line -->
@@ -295,9 +295,9 @@
 
       <div class="flex items-center mb-4" @click="toggleUserProfileLocation">
         <input
+          v-model="includeUserProfileLocation"
           type="checkbox"
           class="mr-2"
-          v-model="includeUserProfileLocation"
         />
         <label for="includeUserProfileLocation">Include Location</label>
       </div>
@@ -333,17 +333,16 @@
       <div v-if="!loadingProfile && !savingProfile">
         <div class="flex justify-between items-center">
           <button
-            @click="saveProfile"
             class="mt-2 px-4 py-2 bg-gradient-to-b from-blue-400 to-blue-700 shadow-[inset_0_-1px_0_0_rgba(0,0,0,0.5)] text-white rounded-md"
             :disabled="loadingProfile || savingProfile"
             :class="{
               'opacity-50 cursor-not-allowed': loadingProfile || savingProfile,
             }"
+            @click="saveProfile"
           >
             Save Profile
           </button>
           <button
-            @click="confirmDeleteProfile"
             class="mt-2 px-4 py-2 bg-gradient-to-b from-red-400 to-red-700 shadow-[inset_0_-1px_0_0_rgba(0,0,0,0.5)] text-white rounded-md"
             :disabled="loadingProfile || savingProfile"
             :class="{
@@ -352,6 +351,7 @@
                 savingProfile ||
                 (!userProfileDesc && !includeUserProfileLocation),
             }"
+            @click="confirmDeleteProfile"
           >
             Delete Profile
           </button>
@@ -426,15 +426,15 @@
     >
       <div class="mb-2 font-bold">Data Export</div>
       <router-link
-        :to="{ name: 'seed-backup' }"
         v-if="activeDid"
+        :to="{ name: 'seed-backup' }"
         class="block w-full text-center text-md bg-gradient-to-b from-blue-400 to-blue-700 shadow-[inset_0_-1px_0_0_rgba(0,0,0,0.5)] text-white px-1.5 py-2 rounded-md mb-2 mt-2"
       >
         Backup Identifier Seed
       </router-link>
 
       <button
-        v-bind:class="computedStartDownloadLinkClassNames()"
+        :class="computedStartDownloadLinkClassNames()"
         class="block w-full text-center text-md bg-gradient-to-b from-blue-400 to-blue-700 shadow-[inset_0_-1px_0_0_rgba(0,0,0,0.5)] text-white px-1.5 py-2 rounded-md"
         @click="exportDatabase()"
       >
@@ -444,7 +444,7 @@
       </button>
       <a
         ref="downloadLink"
-        v-bind:class="computedDownloadLinkClassNames()"
+        :class="computedDownloadLinkClassNames()"
         class="block w-full text-center text-md bg-gradient-to-b from-green-500 to-green-800 shadow-[inset_0_-1px_0_0_rgba(0,0,0,0.5)] text-white px-1.5 py-2 rounded-md mb-6"
       >
         If no download happened yet, click again here to download now.
@@ -476,7 +476,7 @@
     >
       Advanced
     </h3>
-    <div id="sectionAdvanced" v-if="showAdvanced || showGeneralAdvanced">
+    <div v-if="showAdvanced || showGeneralAdvanced" id="sectionAdvanced">
       <p class="text-rose-600 mb-8">
         Beware: the features here can be confusing and even change data in ways
         you do not expect. But we support your freedom!
@@ -496,10 +496,10 @@
         >
           <code class="truncate">{{ publicBase64 }}</code>
           <button
+            class="ml-2"
             @click="
               doCopyTwoSecRedo(publicBase64, () => (showB64Copy = !showB64Copy))
             "
-            class="ml-2"
           >
             <font-awesome
               icon="copy"
@@ -515,10 +515,10 @@
         >
           <code class="truncate">{{ publicHex }}</code>
           <button
+            class="ml-2"
             @click="
               doCopyTwoSecRedo(publicHex, () => (showPubCopy = !showPubCopy))
             "
-            class="ml-2"
           >
             <font-awesome
               icon="copy"
@@ -535,13 +535,13 @@
         >
           <code class="truncate">{{ derivationPath }}</code>
           <button
+            class="ml-2"
             @click="
               doCopyTwoSecRedo(
                 derivationPath,
                 () => (showDerCopy = !showDerCopy),
               )
             "
-            class="ml-2"
           >
             <font-awesome
               icon="copy"
@@ -573,7 +573,7 @@
         </h2>
 
         <div class="ml-4 mt-2">
-          <input type="file" @change="uploadImportFile" class="ml-2" />
+          <input type="file" class="ml-2" @change="uploadImportFile" />
           <transition
             enter-active-class="transform ease-out duration-300 transition"
             enter-from-class="translate-y-2 opacity-0 sm:translate-y-4"
@@ -620,8 +620,8 @@
         <div class="relative ml-2">
           <!-- input -->
           <input
-            type="checkbox"
             v-model="showContactGives"
+            type="checkbox"
             name="showContactGives"
             class="sr-only"
           />
@@ -638,9 +638,9 @@
         <h2 class="text-slate-500 text-sm font-bold mt-4">Claim Server</h2>
         <div class="px-4 py-4">
           <input
+            v-model="apiServerInput"
             type="text"
             class="block w-full rounded border border-slate-400 px-4 py-2"
-            v-model="apiServerInput"
           />
           <button
             v-if="apiServerInput != apiServer"
@@ -683,7 +683,7 @@
           <!-- toggle -->
           <div class="relative ml-2">
             <!-- input -->
-            <input type="checkbox" v-model="warnIfProdServer" class="sr-only" />
+            <input v-model="warnIfProdServer" type="checkbox" class="sr-only" />
             <!-- line -->
             <div class="block bg-slate-500 w-14 h-8 rounded-full"></div>
             <!-- dot -->
@@ -703,7 +703,7 @@
           <!-- toggle -->
           <div class="relative ml-2">
             <!-- input -->
-            <input type="checkbox" v-model="warnIfTestServer" class="sr-only" />
+            <input v-model="warnIfTestServer" type="checkbox" class="sr-only" />
             <!-- line -->
             <div class="block bg-slate-500 w-14 h-8 rounded-full"></div>
             <!-- dot -->
@@ -719,9 +719,9 @@
       </h2>
       <div class="px-3 py-4">
         <input
+          v-model="webPushServerInput"
           type="text"
           class="block w-full rounded border border-slate-400 px-3 py-2"
-          v-model="webPushServerInput"
         />
         <button
           v-if="webPushServerInput != webPushServer"
@@ -753,7 +753,7 @@
           Use Test 2
         </button>
       </div>
-      <span class="px-4 text-sm" v-if="!webPushServerInput">
+      <span v-if="!webPushServerInput" class="px-4 text-sm">
         When that setting is blank, this app will use the default web push
         server URL:
         {{ DEFAULT_PUSH_SERVER }}
@@ -762,9 +762,9 @@
       <h2 class="text-slate-500 text-sm font-bold mb-2">Partner Server URL</h2>
       <div class="px-3 py-4">
         <input
+          v-model="partnerApiServerInput"
           type="text"
           class="block w-full rounded border border-slate-400 px-3 py-2"
-          v-model="partnerApiServerInput"
         />
         <button
           v-if="partnerApiServerInput != partnerApiServer"
@@ -796,7 +796,7 @@
           Use Local
         </button>
       </div>
-      <span class="px-4 text-sm" v-if="!partnerApiServerInput">
+      <span v-if="!partnerApiServerInput" class="px-4 text-sm">
         When that setting is blank, this app will use the default partner server
         URL:
         {{ DEFAULT_PARTNER_API_SERVER }}
@@ -821,8 +821,8 @@
         <div class="relative ml-2">
           <!-- input -->
           <input
-            type="checkbox"
             v-model="hideRegisterPromptOnNewContact"
+            type="checkbox"
             class="sr-only"
           />
           <!-- line -->
@@ -846,7 +846,7 @@
         <!-- toggle -->
         <div class="relative ml-2">
           <!-- input -->
-          <input type="checkbox" v-model="showShortcutBvc" class="sr-only" />
+          <input v-model="showShortcutBvc" type="checkbox" class="sr-only" />
           <!-- line -->
           <div class="block bg-slate-500 w-14 h-8 rounded-full" />
           <!-- dot -->
@@ -879,9 +879,9 @@
         </span>
         <div class="relative ml-2">
           <input
+            v-model="passkeyExpirationMinutes"
             type="number"
             class="border border-slate-400 rounded px-2 py-2 text-center w-20"
-            v-model="passkeyExpirationMinutes"
             @change="updatePasskeyExpiration"
           />
         </div>
@@ -900,8 +900,8 @@
         <div class="relative ml-2">
           <!-- input -->
           <input
-            type="checkbox"
             v-model="showGeneralAdvanced"
+            type="checkbox"
             class="sr-only"
           />
           <!-- line -->
diff --git a/src/views/ClaimAddRawView.vue b/src/views/ClaimAddRawView.vue
index f7d36ac9..a30857a1 100644
--- a/src/views/ClaimAddRawView.vue
+++ b/src/views/ClaimAddRawView.vue
@@ -7,8 +7,8 @@
       <h1 class="text-lg text-center font-light relative px-7">
         <!-- Back -->
         <button
-          @click="$router.go(-1)"
           class="text-lg text-center px-2 py-1 absolute -left-2 -top-1"
+          @click="$router.go(-1)"
         >
           <font-awesome icon="chevron-left" class="fa-fw" />
         </button>
@@ -17,7 +17,7 @@
     </div>
 
     <div class="flex">
-      <textarea rows="20" class="border-2 w-full" v-model="claimStr"></textarea>
+      <textarea v-model="claimStr" rows="20" class="border-2 w-full"></textarea>
     </div>
     <button
       class="block w-full text-center text-lg font-bold uppercase bg-gradient-to-b from-blue-400 to-blue-700 shadow-[inset_0_-1px_0_0_rgba(0,0,0,0.5)] text-white px-2 py-3 rounded-md"
diff --git a/src/views/ClaimCertificateView.vue b/src/views/ClaimCertificateView.vue
index fdf9bb22..7c7bbe85 100644
--- a/src/views/ClaimCertificateView.vue
+++ b/src/views/ClaimCertificateView.vue
@@ -2,8 +2,8 @@
   <section id="Content">
     <div class="flex items-center justify-center h-screen">
       <div v-if="claimData">
-        <router-link :to="'/claim/' + this.claimId">
-          <canvas class="w-full block mx-auto" ref="claimCanvas"></canvas>
+        <router-link :to="'/claim/' + claimId">
+          <canvas ref="claimCanvas" class="w-full block mx-auto"></canvas>
         </router-link>
       </div>
     </div>
diff --git a/src/views/ClaimReportCertificateView.vue b/src/views/ClaimReportCertificateView.vue
index bd9d4ecd..ba7a6177 100644
--- a/src/views/ClaimReportCertificateView.vue
+++ b/src/views/ClaimReportCertificateView.vue
@@ -6,16 +6,6 @@
   </section>
 </template>
 
-<style scoped>
-canvas {
-  position: absolute;
-  top: 0;
-  left: 0;
-  width: 100%;
-  height: 100%;
-}
-</style>
-
 <script lang="ts">
 import { Component, Vue } from "vue-facing-decorator";
 import { nextTick } from "vue";
@@ -188,3 +178,13 @@ export default class ClaimReportCertificateView extends Vue {
   }
 }
 </script>
+
+<style scoped>
+canvas {
+  position: absolute;
+  top: 0;
+  left: 0;
+  width: 100%;
+  height: 100%;
+}
+</style>
diff --git a/src/views/ClaimView.vue b/src/views/ClaimView.vue
index d9e19fef..9e6c5d62 100644
--- a/src/views/ClaimView.vue
+++ b/src/views/ClaimView.vue
@@ -7,8 +7,8 @@
       <h1 class="text-lg text-center font-light relative px-7">
         <!-- Back -->
         <button
-          @click="$router.go(-1)"
           class="text-lg text-center px-2 py-1 absolute -left-2 -top-1"
+          @click="$router.go(-1)"
         >
           <font-awesome icon="chevron-left" class="fa-fw" />
         </button>
@@ -34,9 +34,9 @@
                   // but rather than add more Plan-specific logic to detect the agent
                   // we'll let them click the Project link and edit from there
                 "
-                @click="onClickEditClaim"
                 title="Edit"
                 data-testId="editClaimButton"
+                @click="onClickEditClaim"
               >
                 <font-awesome
                   icon="pen"
@@ -131,10 +131,10 @@
             >
               <!-- router-link to /claim/ only changes URL path -->
               <a
+                class="text-blue-500 mt-4 cursor-pointer"
                 @click="
                   showDifferentClaimPage(detailsForGive?.fulfillsHandleId)
                 "
-                class="text-blue-500 mt-4 cursor-pointer"
               >
                 Fulfills
                 {{
@@ -170,15 +170,15 @@
                   <div class="flex gap-4">
                     <div class="grow overflow-hidden">
                       <a
+                        class="text-blue-500 mt-4 cursor-pointer"
                         @click="
                           provider.identifier.startsWith('did:')
-                            ? this.$router.push(
+                            ? $router.push(
                                 '/did/' +
                                   encodeURIComponent(provider.identifier),
                               )
                             : showDifferentClaimPage(provider.identifier)
                         "
-                        class="text-blue-500 mt-4 cursor-pointer"
                       >
                         an activity...
                       </a>
@@ -207,8 +207,8 @@
     <div class="mt-8">
       <button
         v-if="libsUtil.canFulfillOffer(veriClaim)"
-        @click="openFulfillGiftDialog()"
         class="col-span-1 block w-fit text-center text-md bg-gradient-to-b from-blue-400 to-blue-700 shadow-[inset_0_-1px_0_0_rgba(0,0,0,0.5)] text-white px-1.5 py-2 rounded-md"
+        @click="openFulfillGiftDialog()"
       >
         Affirm Delivery
         <font-awesome
@@ -222,7 +222,6 @@
     <div v-if="libsUtil.isGiveAction(veriClaim)">
       <div class="flex columns-3">
         <button
-          class="col-span-1 bg-gradient-to-b from-blue-400 to-blue-700 shadow-[inset_0_-1px_0_0_rgba(0,0,0,0.5)] text-white mt-2 px-4 py-2 rounded-md"
           v-if="
             libsUtil.isGiveRecordTheUserCanConfirm(
               isRegistered,
@@ -231,6 +230,7 @@
               confirmerIdList,
             )
           "
+          class="col-span-1 bg-gradient-to-b from-blue-400 to-blue-700 shadow-[inset_0_-1px_0_0_rgba(0,0,0,0.5)] text-white mt-2 px-4 py-2 rounded-md"
           @click="confirmConfirmClaim()"
         >
           Confirm
@@ -388,7 +388,7 @@
         <span v-if="canShare">
           You can ask one of your contacts to take a look and see if their
           contacts can see more details:
-          <a @click="onClickShareClaim()" class="text-blue-500"
+          <a class="text-blue-500" @click="onClickShareClaim()"
             >click to send them this page info</a
           >
           and see if they can make an introduction. Someone is connected to
@@ -399,8 +399,8 @@
           You can ask one of your contacts to take a look and see if their
           contacts can see more details:
           <a
-            @click="copyToClipboard('A link to this page', windowLocation)"
             class="text-blue-500"
+            @click="copyToClipboard('A link to this page', windowLocation)"
             >click to copy this page info</a
           >
           and see if they can make an introduction. Someone is connected to
@@ -414,7 +414,7 @@
         of your contacts.
         <span v-if="canShare">
           If you'd like an introduction,
-          <a @click="onClickShareClaim()" class="text-blue-500"
+          <a class="text-blue-500" @click="onClickShareClaim()"
             >click to share the information with them and ask if they'll tell
             you more about the participants.</a
           >
@@ -422,8 +422,8 @@
         <span v-else>
           If you'd like an introduction,
           <a
-            @click="copyToClipboard('A link to this page', windowLocation)"
             class="text-blue-500"
+            @click="copyToClipboard('A link to this page', windowLocation)"
             >share this page with them and ask if they'll tell you more about
             about the participants.</a
           >
diff --git a/src/views/ConfirmGiftView.vue b/src/views/ConfirmGiftView.vue
index 3c3c01ef..b5c1e207 100644
--- a/src/views/ConfirmGiftView.vue
+++ b/src/views/ConfirmGiftView.vue
@@ -8,8 +8,8 @@
       <h1 class="text-lg text-center font-light relative px-7">
         <!-- Back -->
         <button
-          @click="$router.go(-1)"
           class="text-lg text-center px-2 py-1 absolute -left-2 -top-1"
+          @click="$router.go(-1)"
         >
           <font-awesome icon="chevron-left" class="fa-fw" />
         </button>
@@ -32,7 +32,6 @@
     <div v-if="giveDetails && !isLoading">
       <div class="flex justify-center">
         <button
-          class="col-span-1 bg-gradient-to-b from-blue-400 to-blue-700 shadow-[inset_0_-1px_0_0_rgba(0,0,0,0.5)] text-white px-4 py-2 rounded-md"
           v-if="
             libsUtil.isGiveRecordTheUserCanConfirm(
               isRegistered,
@@ -41,6 +40,7 @@
               confirmerIdList,
             )
           "
+          class="col-span-1 bg-gradient-to-b from-blue-400 to-blue-700 shadow-[inset_0_-1px_0_0_rgba(0,0,0,0.5)] text-white px-4 py-2 rounded-md"
           @click="confirmConfirmClaim()"
         >
           Confirm
@@ -51,8 +51,8 @@
         </button>
         <button
           v-else
-          @click="notifyWhyCannotConfirm()"
           class="col-span-1 bg-gradient-to-b from-slate-400 to-slate-700 shadow-[inset_0_-1px_0_0_rgba(0,0,0,0.5)] text-white px-4 py-2 rounded-md"
+          @click="notifyWhyCannotConfirm()"
         >
           Confirm
           <font-awesome
@@ -98,7 +98,7 @@
               <!-- Fullfills Links -->
 
               <!-- fullfills links for a give -->
-              <div class="mt-2" v-if="giveDetails?.fulfillsPlanHandleId">
+              <div v-if="giveDetails?.fulfillsPlanHandleId" class="mt-2">
                 <router-link
                   :to="
                     '/project/' +
@@ -297,7 +297,7 @@
           <span v-if="canShare">
             You can ask one of your contacts to take a look and see if their
             contacts can see more details:
-            <a @click="onClickShareClaim()" class="text-blue-500"
+            <a class="text-blue-500" @click="onClickShareClaim()"
               >click to send them this page info</a
             >
             and see if they can make an introduction. Someone is connected to
@@ -308,8 +308,8 @@
             You can ask one of your contacts to take a look and see if their
             contacts can see more details:
             <a
-              @click="copyToClipboard('A link to this page', windowLocation)"
               class="text-blue-500"
+              @click="copyToClipboard('A link to this page', windowLocation)"
               >click to copy this page info</a
             >
             and see if they can make an introduction. Someone is connected to
@@ -323,7 +323,7 @@
           some of your contacts.
           <span v-if="canShare">
             If you'd like an introduction,
-            <a @click="onClickShareClaim()" class="text-blue-500"
+            <a class="text-blue-500" @click="onClickShareClaim()"
               >click to share the information with them and ask if they'll tell
               you more about the participants.</a
             >
@@ -331,8 +331,8 @@
           <span v-else>
             If you'd like an introduction,
             <a
-              @click="copyToClipboard('A link to this page', windowLocation)"
               class="text-blue-500"
+              @click="copyToClipboard('A link to this page', windowLocation)"
               >share this page with them and ask if they'll tell you more about
               about the participants.</a
             >
@@ -399,8 +399,8 @@
         >
         <div class="mt-2 ml-2">
           <a
-            @click="showClaimPage(veriClaim.id)"
             class="text-blue-500 cursor-pointer"
+            @click="showClaimPage(veriClaim.id)"
           >
             <font-awesome icon="file-lines" />
             See All Generic Info
@@ -421,8 +421,8 @@
     <div v-else-if="!isLoading">This does not have details to confirm.</div>
 
     <div
-      class="fixed left-6 bottom-24 text-center text-4xl leading-none bg-slate-400 text-white w-14 py-2.5 rounded-full"
       v-if="isLoading"
+      class="fixed left-6 bottom-24 text-center text-4xl leading-none bg-slate-400 text-white w-14 py-2.5 rounded-full"
     >
       <font-awesome icon="spinner" class="fa-spin-pulse"></font-awesome>
     </div>
diff --git a/src/views/ContactAmountsView.vue b/src/views/ContactAmountsView.vue
index bd73dad3..9eb5eb38 100644
--- a/src/views/ContactAmountsView.vue
+++ b/src/views/ContactAmountsView.vue
@@ -64,7 +64,7 @@
                     class="text-green-600 fa-fw"
                   />
                 </span>
-                <button v-else @click="confirm(record)" title="Unconfirmed">
+                <button v-else title="Unconfirmed" @click="confirm(record)">
                   <font-awesome icon="circle" class="text-blue-600 fa-fw" />
                 </button>
               </div>
@@ -93,8 +93,8 @@
                 </span>
                 <button
                   v-else
-                  @click="cannotConfirmMessage()"
                   title="Unconfirmed"
+                  @click="cannotConfirmMessage()"
                 >
                   <font-awesome icon="circle" class="text-slate-600 fa-fw" />
                 </button>
diff --git a/src/views/ContactEditView.vue b/src/views/ContactEditView.vue
index 3a8735b4..11113966 100644
--- a/src/views/ContactEditView.vue
+++ b/src/views/ContactEditView.vue
@@ -7,8 +7,8 @@
       <h1 class="text-4xl text-center font-light relative px-7">
         <!-- Back -->
         <button
-          @click="$router.go(-1)"
           class="text-lg text-center px-2 py-1 absolute -left-2 -top-1"
+          @click="$router.go(-1)"
         >
           <font-awesome icon="chevron-left" class="fa-fw" />
         </button>
@@ -25,9 +25,9 @@
         Name
       </label>
       <input
+        v-model="contactName"
         type="text"
         class="block w-full ml-2 mt-1 border border-gray-300 rounded-md shadow-sm focus:ring-indigo-500 focus:border-indigo-500"
-        v-model="contactName"
       />
     </div>
 
@@ -38,9 +38,9 @@
       </label>
       <textarea
         id="contactNotes"
+        v-model="contactNotes"
         rows="4"
         class="block w-full mt-1 border border-gray-300 rounded-md shadow-sm focus:ring-indigo-500 focus:border-indigo-500"
-        v-model="contactNotes"
       ></textarea>
     </div>
 
@@ -53,21 +53,21 @@
         class="flex mt-2"
       >
         <input
-          type="text"
           v-model="method.label"
+          type="text"
           class="block w-1/4 border border-gray-300 rounded-md shadow-sm focus:ring-indigo-500 focus:border-indigo-500"
           placeholder="Label"
         />
         <input
-          type="text"
           v-model="method.type"
+          type="text"
           class="block ml-2 w-1/4 border border-gray-300 rounded-md shadow-sm focus:ring-indigo-500 focus:border-indigo-500"
           placeholder="Type"
         />
         <div class="relative">
           <button
-            @click="toggleDropdown(index)"
             class="px-2 py-1 bg-gray-200 rounded-md"
+            @click="toggleDropdown(index)"
           >
             <font-awesome icon="caret-down" class="fa-fw" />
           </button>
@@ -76,36 +76,36 @@
             class="absolute bg-white border border-gray-300 rounded-md mt-1"
           >
             <div
-              @click="setMethodType(index, 'CELL')"
               class="px-4 py-2 hover:bg-gray-100 cursor-pointer"
+              @click="setMethodType(index, 'CELL')"
             >
               CELL
             </div>
             <div
-              @click="setMethodType(index, 'EMAIL')"
               class="px-4 py-2 hover:bg-gray-100 cursor-pointer"
+              @click="setMethodType(index, 'EMAIL')"
             >
               EMAIL
             </div>
             <div
-              @click="setMethodType(index, 'WHATSAPP')"
               class="px-4 py-2 hover:bg-gray-100 cursor-pointer"
+              @click="setMethodType(index, 'WHATSAPP')"
             >
               WHATSAPP
             </div>
           </div>
         </div>
         <input
-          type="text"
           v-model="method.value"
+          type="text"
           class="block ml-2 w-1/2 border border-gray-300 rounded-md shadow-sm focus:ring-indigo-500 focus:border-indigo-500"
           placeholder="Number, email, etc."
         />
-        <button @click="removeContactMethod(index)" class="ml-2 text-red-500">
+        <button class="ml-2 text-red-500" @click="removeContactMethod(index)">
           <font-awesome icon="trash-can" class="fa-fw" />
         </button>
       </div>
-      <button @click="addContactMethod" class="mt-2">
+      <button class="mt-2" @click="addContactMethod">
         <font-awesome
           icon="plus"
           class="fa-fw px-2 py-2.5 bg-green-500 text-green-100 rounded-full"
diff --git a/src/views/ContactGiftingView.vue b/src/views/ContactGiftingView.vue
index f54ebe6a..164f46d8 100644
--- a/src/views/ContactGiftingView.vue
+++ b/src/views/ContactGiftingView.vue
@@ -30,8 +30,8 @@
           <span class="text-right">
             <button
               type="button"
-              @click="openDialog()"
               class="block w-full text-center text-sm uppercase bg-gradient-to-b from-blue-400 to-blue-700 shadow-[inset_0_-1px_0_0_rgba(0,0,0,0.5)] text-white px-3 py-1.5 rounded-md"
+              @click="openDialog()"
             >
               <font-awesome icon="gift" class="fa-fw"></font-awesome>
             </button>
@@ -47,7 +47,7 @@
           <span class="grow font-semibold">
             <EntityIcon
               :contact="contact"
-              :iconSize="32"
+              :icon-size="32"
               class="inline-block align-middle border border-slate-300 rounded-md mr-1"
             />
             {{ contact.name || "(no name)" }}
@@ -55,8 +55,8 @@
           <span class="text-right">
             <button
               type="button"
-              @click="openDialog(contact)"
               class="block w-full text-center text-sm uppercase bg-gradient-to-b from-blue-400 to-blue-700 shadow-[inset_0_-1px_0_0_rgba(0,0,0,0.5)] text-white px-3 py-1.5 rounded-md"
+              @click="openDialog(contact)"
             >
               <font-awesome icon="gift" class="fa-fw"></font-awesome>
             </button>
@@ -65,7 +65,7 @@
       </li>
     </ul>
 
-    <GiftedDialog ref="customDialog" :toProjectId="projectId" />
+    <GiftedDialog ref="customDialog" :to-project-id="projectId" />
   </section>
 </template>
 
diff --git a/src/views/ContactImportView.vue b/src/views/ContactImportView.vue
index 729e5aac..12fd3d06 100644
--- a/src/views/ContactImportView.vue
+++ b/src/views/ContactImportView.vue
@@ -24,7 +24,7 @@
         v-if="contactsImporting.length > sameCount"
         class="flex justify-center"
       >
-        <input type="checkbox" v-model="makeVisible" class="mr-2" />
+        <input v-model="makeVisible" type="checkbox" class="mr-2" />
         Make my activity visible to these contacts.
       </span>
 
@@ -51,7 +51,7 @@
             class="grow overflow-hidden border-b border-slate-300 pt-2.5 pb-4"
           >
             <h2 class="text-base font-semibold">
-              <input type="checkbox" v-model="contactsSelected[index]" />
+              <input v-model="contactsSelected[index]" type="checkbox" />
               {{ contact.name || AppString.NO_CONTACT_NAME }}
               -
               <span v-if="contactsExisting[contact.did]" class="text-orange-500"
@@ -110,8 +110,8 @@
           />
           <br />
           <button
-            @click="() => processContactJwt(inputJwt)"
             class="ml-2 p-2 bg-blue-500 text-white rounded"
+            @click="() => processContactJwt(inputJwt)"
           >
             Check Import
           </button>
diff --git a/src/views/ContactQRScanShowView.vue b/src/views/ContactQRScanShowView.vue
index c49af381..cd094197 100644
--- a/src/views/ContactQRScanShowView.vue
+++ b/src/views/ContactQRScanShowView.vue
@@ -26,10 +26,8 @@
         You aren't sharing your name, so quickly
         <br />
         <span
-          @click="
-            () => $refs.userNameDialog.open((name) => (this.givenName = name))
-          "
           class="bg-gradient-to-b from-blue-400 to-blue-700 shadow-[inset_0_-1px_0_0_rgba(0,0,0,0.5)] text-white px-1.5 py-1 rounded-md"
+          @click="() => $refs.userNameDialog.open((name) => (givenName = name))"
         >
           click here to set it for them.
         </span>
@@ -38,18 +36,18 @@
     <UserNameDialog ref="userNameDialog" />
 
     <div
-      @click="onCopyUrlToClipboard()"
       v-if="activeDid && activeDid.startsWith(ETHR_DID_PREFIX)"
       class="text-center"
+      @click="onCopyUrlToClipboard()"
     >
       <!--
         Play with display options: https://qr-code-styling.com/
         See docs: https://www.npmjs.com/package/qr-code-generator-vue3
       -->
       <QRCodeVue3
-        :value="this.qrValue"
-        :cornersSquareOptions="{ type: 'extra-rounded' }"
-        :dotsOptions="{ type: 'square' }"
+        :value="qrValue"
+        :corners-square-options="{ type: 'extra-rounded' }"
+        :dots-options="{ type: 'square' }"
         class="flex justify-center"
       />
       <span>
@@ -58,14 +56,14 @@
     </div>
     <div v-else-if="activeDid" class="text-center">
       <!-- Not an ETHR DID so force them to paste it. (Passkey Peer DIDs are too big.) -->
-      <span @click="onCopyDidToClipboard()" class="text-blue-500">
+      <span class="text-blue-500" @click="onCopyDidToClipboard()">
         Click here to copy your DID to your clipboard.
       </span>
       <span>
         Then give it to them so they can paste it in their list of People.
       </span>
     </div>
-    <div class="text-center" v-else>
+    <div v-else class="text-center">
       You have no identitifiers yet, so
       <router-link
         :to="{ name: 'start' }"
diff --git a/src/views/ContactsView.vue b/src/views/ContactsView.vue
index 75ccc6b7..f6707396 100644
--- a/src/views/ContactsView.vue
+++ b/src/views/ContactsView.vue
@@ -23,7 +23,7 @@
 
     <!-- New Contact -->
     <div id="formAddNewContact" class="mt-4 mb-4 flex items-stretch">
-      <span class="flex" v-if="isRegistered">
+      <span v-if="isRegistered" class="flex">
         <router-link
           :to="{ name: 'invite-one' }"
           class="flex items-center bg-gradient-to-b from-green-400 to-green-700 shadow-[inset_0_-1px_0_0_rgba(0,0,0,0.5)] text-white px-1.5 py-1 mr-1 rounded-md"
@@ -32,8 +32,8 @@
         </router-link>
 
         <button
-          @click="showOnboardMeetingDialog()"
           class="flex items-center bg-gradient-to-b from-green-400 to-green-700 shadow-[inset_0_-1px_0_0_rgba(0,0,0,0.5)] text-white px-1.5 py-1 mr-1 rounded-md"
+          @click="showOnboardMeetingDialog()"
         >
           <font-awesome icon="chair" class="fa-fw text-2xl" />
         </button>
@@ -77,10 +77,10 @@
       </router-link>
 
       <textarea
+        v-model="contactInput"
         type="text"
         placeholder="New URL or DID, Name, Public Key, Next Public Key Hash"
         class="block w-full rounded-l border border-r-0 border-slate-400 px-3 py-2 h-10"
-        v-model="contactInput"
       />
       <button
         class="px-4 rounded-r bg-green-200 border border-l-0 border-green-400"
@@ -90,21 +90,22 @@
       </button>
     </div>
 
-    <div class="flex justify-between" v-if="contacts.length > 0">
+    <div v-if="contacts.length > 0" class="flex justify-between">
       <div class="w-full text-left">
         <div v-if="!showGiveNumbers">
           <input
             type="checkbox"
             :checked="contactsSelected.length === contacts.length"
+            class="align-middle ml-2 h-6 w-6"
+            data-testId="contactCheckAllTop"
             @click="
               contactsSelected.length === contacts.length
                 ? (contactsSelected = [])
                 : (contactsSelected = contacts.map((contact) => contact.did))
             "
-            class="align-middle ml-2 h-6 w-6"
-            data-testId="contactCheckAllTop"
           />
           <button
+            v-if="!showGiveNumbers"
             href=""
             class="text-md bg-gradient-to-b shadow-[inset_0_-1px_0_0_rgba(0,0,0,0.5)] text-white ml-2 px-1 py-1 rounded-md"
             :style="
@@ -112,9 +113,8 @@
                 ? 'background-image: linear-gradient(to bottom, #3b82f6, #1e40af);'
                 : 'background-image: linear-gradient(to bottom, #94a3b8, #374151);'
             "
-            @click="copySelectedContacts()"
-            v-if="!showGiveNumbers"
             data-testId="copySelectedContactsButtonTop"
+            @click="copySelectedContacts()"
           >
             Copy Selections
           </button>
@@ -139,7 +139,7 @@
         </button>
       </div>
     </div>
-    <div class="flex justify-between mt-1" v-if="showGiveNumbers">
+    <div v-if="showGiveNumbers" class="flex justify-between mt-1">
       <div class="w-full text-right">
         In the following, only the most recent hours are included. To see more,
         click
@@ -152,7 +152,7 @@
         <button
           href=""
           class="text-md bg-gradient-to-b shadow-[inset_0_-1px_0_0_rgba(0,0,0,0.5)] text-white px-1.5 py-1 rounded-md mt-1"
-          v-bind:class="showGiveAmountsClassNames()"
+          :class="showGiveAmountsClassNames()"
           @click="toggleShowGiveTotals()"
         >
           {{
@@ -169,29 +169,31 @@
 
     <!-- Results List -->
     <ul
-      id="listContacts"
       v-if="contacts.length > 0"
+      id="listContacts"
       class="border-t border-slate-300 mt-1"
     >
       <li
-        class="border-b border-slate-300 pt-1 pb-1"
         v-for="contact in filteredContacts()"
         :key="contact.did"
+        class="border-b border-slate-300 pt-1 pb-1"
         data-testId="contactListItem"
       >
         <div class="grow overflow-hidden">
           <div class="flex items-center">
             <EntityIcon
               :contact="contact"
-              :iconSize="24"
+              :icon-size="24"
               class="inline-block align-text-bottom border border-slate-300 rounded cursor-pointer"
               @click="showLargeIdenticon = contact"
             />
 
             <input
-              type="checkbox"
               v-if="!showGiveNumbers"
+              type="checkbox"
               :checked="contactsSelected.includes(contact.did)"
+              class="ml-2 h-6 w-6 flex-shrink-0"
+              data-testId="contactCheckOne"
               @click="
                 contactsSelected.includes(contact.did)
                   ? contactsSelected.splice(
@@ -200,8 +202,6 @@
                     )
                   : contactsSelected.push(contact.did)
               "
-              class="ml-2 h-6 w-6 flex-shrink-0"
-              data-testId="contactCheckOne"
             />
 
             <h2
@@ -240,17 +240,17 @@
             >
               <button
                 class="text-sm bg-gradient-to-b from-blue-400 to-blue-700 shadow-[inset_0_-1px_0_0_rgba(0,0,0,0.5)] text-white px-2 py-1.5 rounded-l-md"
-                @click="confirmShowGiftedDialog(contact.did, activeDid)"
                 :title="givenToMeDescriptions[contact.did] || ''"
+                @click="confirmShowGiftedDialog(contact.did, activeDid)"
               >
                 From:
                 <br />
                 {{
                   /* eslint-disable prettier/prettier */
-                  this.showGiveTotals
+                  showGiveTotals
                     ? ((givenToMeConfirmed[contact.did] || 0)
                         + (givenToMeUnconfirmed[contact.did] || 0))
-                    : this.showGiveConfirmed
+                    : showGiveConfirmed
                         ? (givenToMeConfirmed[contact.did] || 0)
                         : (givenToMeUnconfirmed[contact.did] || 0)
                   /* eslint-enable prettier/prettier */
@@ -259,17 +259,17 @@
 
               <button
                 class="text-sm bg-gradient-to-b from-blue-400 to-blue-700 shadow-[inset_0_-1px_0_0_rgba(0,0,0,0.5)] text-white -ml-1.5 px-2 py-1.5 rounded-r-md border-l"
-                @click="confirmShowGiftedDialog(activeDid, contact.did)"
                 :title="givenByMeDescriptions[contact.did] || ''"
+                @click="confirmShowGiftedDialog(activeDid, contact.did)"
               >
                 To:
                 <br />
                 {{
                   /* eslint-disable prettier/prettier */
-                  this.showGiveTotals
+                  showGiveTotals
                     ? ((givenByMeConfirmed[contact.did] || 0)
                       + (givenByMeUnconfirmed[contact.did] || 0))
-                    : this.showGiveConfirmed
+                    : showGiveConfirmed
                         ? (givenByMeConfirmed[contact.did] || 0)
                         : (givenByMeUnconfirmed[contact.did] || 0)
                   /* eslint-enable prettier/prettier */
@@ -278,8 +278,8 @@
 
               <button
                 class="text-sm bg-gradient-to-b from-blue-400 to-blue-700 shadow-[inset_0_-1px_0_0_rgba(0,0,0,0.5)] text-white px-2 py-1.5 rounded-md border border-blue-400"
-                @click="openOfferDialog(contact.did, contact.name)"
                 data-testId="offerButton"
+                @click="openOfferDialog(contact.did, contact.name)"
               >
                 Offer
               </button>
@@ -301,20 +301,21 @@
     </ul>
     <p v-else>There are no contacts.</p>
 
-    <div class="mt-2 w-full text-left" v-if="contacts.length > 0">
+    <div v-if="contacts.length > 0" class="mt-2 w-full text-left">
       <input
-        type="checkbox"
         v-if="!showGiveNumbers"
+        type="checkbox"
         :checked="contactsSelected.length === contacts.length"
+        class="align-middle ml-2 h-6 w-6"
+        data-testId="contactCheckAllBottom"
         @click="
           contactsSelected.length === contacts.length
             ? (contactsSelected = [])
             : (contactsSelected = contacts.map((contact) => contact.did))
         "
-        class="align-middle ml-2 h-6 w-6"
-        data-testId="contactCheckAllBottom"
       />
       <button
+        v-if="!showGiveNumbers"
         href=""
         class="text-md bg-gradient-to-b from-slate-400 to-slate-700 shadow-[inset_0_-1px_0_0_rgba(0,0,0,0.5)] text-white ml-2 px-1 py-1 rounded-md"
         :style="
@@ -323,7 +324,6 @@
             : 'background-image: linear-gradient(to bottom, #94a3b8, #374151);'
         "
         @click="copySelectedContacts()"
-        v-if="!showGiveNumbers"
       >
         Copy Selections
       </button>
@@ -339,7 +339,7 @@
       >
         <EntityIcon
           :contact="showLargeIdenticon"
-          :iconSize="512"
+          :icon-size="512"
           class="flex w-11/12 max-w-sm mx-auto mb-3 overflow-hidden bg-white rounded-lg shadow-lg"
           @click="showLargeIdenticon = undefined"
         />
diff --git a/src/views/DIDView.vue b/src/views/DIDView.vue
index 1928e7c7..4ff476c5 100644
--- a/src/views/DIDView.vue
+++ b/src/views/DIDView.vue
@@ -9,8 +9,8 @@
       <h1 id="ViewHeading" class="text-lg text-center font-light relative px-7">
         <!-- Back -->
         <button
-          @click="$router.go(-1)"
           class="text-lg text-center px-2 py-1 absolute -left-2 -top-1"
+          @click="$router.go(-1)"
         >
           <font-awesome icon="chevron-left" class="fa-fw"></font-awesome>
         </button>
@@ -33,8 +33,8 @@
           </router-link>
         </h2>
         <button
-          @click="showDidDetails = !showDidDetails"
           class="ml-2 mr-2 mt-4"
+          @click="showDidDetails = !showDidDetails"
         >
           Details
           <font-awesome
@@ -58,7 +58,7 @@
         >
           <EntityIcon
             :icon-size="96"
-            :profileImageUrl="contactFromDid?.profileImageUrl"
+            :profile-image-url="contactFromDid?.profileImageUrl"
             class="inline-block align-text-bottom border border-slate-300 rounded"
             @click="showLargeIdenticonUrl = contactFromDid?.profileImageUrl"
           />
@@ -73,8 +73,8 @@
                   contactFromDid?.seesMe && contactFromDid.did !== activeDid
                 "
                 class="text-sm uppercase bg-gradient-to-b from-slate-400 to-slate-700 shadow-[inset_0_-1px_0_0_rgba(0,0,0,0.5)] text-white mx-0.5 my-0.5 px-2 py-1.5 rounded-md"
-                @click="confirmSetVisibility(contactFromDid, false)"
                 title="They can see you"
+                @click="confirmSetVisibility(contactFromDid, false)"
               >
                 <font-awesome icon="eye" class="fa-fw" />
               </button>
@@ -83,27 +83,27 @@
                   !contactFromDid?.seesMe && contactFromDid?.did !== activeDid
                 "
                 class="text-sm uppercase bg-gradient-to-b from-slate-400 to-slate-700 shadow-[inset_0_-1px_0_0_rgba(0,0,0,0.5)] text-white mx-0.5 my-0.5 px-2 py-1.5 rounded-md"
-                @click="confirmSetVisibility(contactFromDid, true)"
                 title="They cannot see you"
+                @click="confirmSetVisibility(contactFromDid, true)"
               >
                 <font-awesome icon="eye-slash" class="fa-fw" />
               </button>
 
               <button
+                v-if="contactFromDid?.did !== activeDid"
                 class="text-sm uppercase bg-gradient-to-b from-slate-400 to-slate-700 shadow-[inset_0_-1px_0_0_rgba(0,0,0,0.5)] text-white mx-0.5 my-0.5 px-2 py-1.5 rounded-md"
-                @click="checkVisibility(contactFromDid)"
                 title="Check Visibility"
-                v-if="contactFromDid?.did !== activeDid"
+                @click="checkVisibility(contactFromDid)"
               >
                 <font-awesome icon="rotate" class="fa-fw" />
               </button>
             </div>
 
             <button
-              @click="confirmRegister(contactFromDid)"
-              class="text-sm uppercase bg-gradient-to-b from-slate-400 to-slate-700 shadow-[inset_0_-1px_0_0_rgba(0,0,0,0.5)] text-white ml-6 mx-0.5 my-0.5 px-2 py-1.5 rounded-md"
               v-if="contactFromDid?.did !== activeDid"
+              class="text-sm uppercase bg-gradient-to-b from-slate-400 to-slate-700 shadow-[inset_0_-1px_0_0_rgba(0,0,0,0.5)] text-white ml-6 mx-0.5 my-0.5 px-2 py-1.5 rounded-md"
               title="Registration"
+              @click="confirmRegister(contactFromDid)"
             >
               <font-awesome
                 v-if="contactFromDid?.registered"
@@ -119,9 +119,9 @@
           </div>
 
           <button
-            @click="confirmDeleteContact(contactFromDid)"
             class="text-sm uppercase bg-gradient-to-b from-rose-500 to-rose-800 shadow-[inset_0_-1px_0_0_rgba(0,0,0,0.5)] text-white ml-6 mx-0.5 my-0.5 px-2 py-1.5 rounded-md"
             title="Delete"
+            @click="confirmDeleteContact(contactFromDid)"
           >
             <font-awesome icon="trash-can" class="fa-fw" />
           </button>
@@ -130,8 +130,8 @@
           <div>Auto-Generated Icon</div>
           <div class="flex justify-center">
             <EntityIcon
-              :entityId="viewingDid"
-              :iconSize="64"
+              :entity-id="viewingDid"
+              :icon-size="64"
               class="inline-block align-middle border border-slate-300 rounded-md mr-1"
               @click="showLargeIdenticonId = viewingDid"
             />
@@ -146,9 +146,9 @@
           class="absolute inset-0 h-screen flex flex-col items-center justify-center bg-slate-900/50"
         >
           <EntityIcon
-            :entityId="showLargeIdenticonId"
-            :iconSize="512"
-            :profileImageUrl="showLargeIdenticonUrl"
+            :entity-id="showLargeIdenticonId"
+            :icon-size="512"
+            :profile-image-url="showLargeIdenticonUrl"
             class="flex w-11/12 max-w-sm mx-auto mb-3 overflow-hidden bg-white rounded-lg shadow-lg"
             @click="
               showLargeIdenticonId = undefined;
@@ -169,8 +169,8 @@
 
     <!-- Loading Animation -->
     <div
-      class="fixed left-6 bottom-24 text-center text-4xl leading-none bg-slate-400 text-white w-14 py-2.5 rounded-full"
       v-if="isLoading"
+      class="fixed left-6 bottom-24 text-center text-4xl leading-none bg-slate-400 text-white w-14 py-2.5 rounded-full"
     >
       <font-awesome icon="spinner" class="fa-spin-pulse"></font-awesome>
     </div>
@@ -183,9 +183,9 @@
     <InfiniteScroll @reached-bottom="loadMoreData">
       <ul>
         <li
-          class="border-b border-slate-300"
           v-for="claim in claims"
           :key="claim.handleId"
+          class="border-b border-slate-300"
         >
           <div class="grid grid-cols-12 gap-4">
             <span class="col-span-2">
@@ -201,7 +201,7 @@
               {{ claimDescription(claim) }}
             </span>
             <span class="col-span-1">
-              <a @click="onClickLoadClaim(claim.id)" class="cursor-pointer">
+              <a class="cursor-pointer" @click="onClickLoadClaim(claim.id)">
                 <font-awesome
                   icon="file-lines"
                   class="pl-2 pt-1 text-blue-500"
diff --git a/src/views/DiscoverView.vue b/src/views/DiscoverView.vue
index 4a291c23..9a2f8eff 100644
--- a/src/views/DiscoverView.vue
+++ b/src/views/DiscoverView.vue
@@ -18,11 +18,11 @@
       :style="{ visibility: isSearchVisible ? 'visible' : 'hidden' }"
     >
       <input
-        type="text"
         v-model="searchTerms"
+        type="text"
         placeholder="Search…"
         class="block w-full rounded-l border border-r-0 border-slate-400 px-3 py-2"
-        v-on:keyup.enter="searchSelected()"
+        @keyup.enter="searchSelected()"
       />
       <button
         class="px-4 rounded-r bg-slate-200 border border-l-0 border-slate-400"
@@ -39,6 +39,7 @@
         <li>
           <a
             href="#"
+            :class="computedProjectsTabStyleClassNames()"
             @click="
               projects = [];
               userProfiles = [];
@@ -46,7 +47,6 @@
               isPeopleActive = false;
               searchSelected();
             "
-            v-bind:class="computedProjectsTabStyleClassNames()"
           >
             Projects
           </a>
@@ -54,6 +54,7 @@
         <li>
           <a
             href="#"
+            :class="computedPeopleTabStyleClassNames()"
             @click="
               projects = [];
               userProfiles = [];
@@ -61,7 +62,6 @@
               isPeopleActive = true;
               searchSelected();
             "
-            v-bind:class="computedPeopleTabStyleClassNames()"
           >
             People
           </a>
@@ -75,6 +75,7 @@
         <li>
           <a
             href="#"
+            :class="computedLocalTabStyleClassNames()"
             @click="
               projects = [];
               userProfiles = [];
@@ -85,7 +86,6 @@
               tempSearchBox = null;
               searchLocal();
             "
-            v-bind:class="computedLocalTabStyleClassNames()"
           >
             Nearby
             <!-- restore when the links don't jump around for different numbers
@@ -101,6 +101,7 @@
         <li>
           <a
             href="#"
+            :class="computedMappedTabStyleClassNames()"
             @click="
               projects = [];
               userProfiles = [];
@@ -111,7 +112,6 @@
               searchTerms = '';
               tempSearchBox = null;
             "
-            v-bind:class="computedMappedTabStyleClassNames()"
           >
             <!-- search is triggered when map component gets to "ready" state -->
             Mapped
@@ -120,6 +120,7 @@
         <li>
           <a
             href="#"
+            :class="computedRemoteTabStyleClassNames()"
             @click="
               projects = [];
               userProfiles = [];
@@ -130,7 +131,6 @@
               tempSearchBox = null;
               searchAll();
             "
-            v-bind:class="computedRemoteTabStyleClassNames()"
           >
             Anywhere
             <!-- restore when the links don't jump around for different numbers
@@ -179,8 +179,8 @@
 
     <!-- Loading Animation -->
     <div
-      class="fixed left-6 bottom-24 text-center text-4xl leading-none bg-slate-400 text-white w-14 py-2.5 rounded-full"
       v-if="isLoading"
+      class="fixed left-6 bottom-24 text-center text-4xl leading-none bg-slate-400 text-white w-14 py-2.5 rounded-full"
     >
       <font-awesome icon="spinner" class="fa-spin-pulse"></font-awesome>
     </div>
@@ -205,19 +205,19 @@
         <!-- Projects List -->
         <template v-if="isProjectsActive">
           <li
-            class="border-b border-slate-300"
             v-for="project in projects"
             :key="project.handleId"
+            class="border-b border-slate-300"
           >
             <a
-              @click="onClickLoadItem(project.handleId)"
               class="block py-4 flex gap-4 cursor-pointer"
+              @click="onClickLoadItem(project.handleId)"
             >
               <div>
                 <ProjectIcon
-                  :entityId="project.handleId"
-                  :iconSize="48"
-                  :imageUrl="project.image"
+                  :entity-id="project.handleId"
+                  :icon-size="48"
+                  :image-url="project.image"
                   class="block border border-slate-300 rounded-md max-h-12 max-w-12"
                 />
               </div>
@@ -246,13 +246,13 @@
         <!-- Profiles List -->
         <template v-else>
           <li
-            class="border-b border-slate-300"
             v-for="profile in userProfiles"
             :key="profile.issuerDid"
+            class="border-b border-slate-300"
           >
             <a
-              @click="onClickLoadItem(profile?.rowId || '')"
               class="block py-4 flex gap-4 cursor-pointer"
+              @click="onClickLoadItem(profile?.rowId || '')"
             >
               <div class="grow">
                 <div class="text-sm">
diff --git a/src/views/GiftedDetailsView.vue b/src/views/GiftedDetailsView.vue
index aaacc97c..7b3e3d07 100644
--- a/src/views/GiftedDetailsView.vue
+++ b/src/views/GiftedDetailsView.vue
@@ -44,9 +44,9 @@
       >
     </h1>
     <textarea
+      v-model="description"
       class="block w-full rounded border border-slate-400 mb-2 px-3 py-2"
       placeholder="What was received"
-      v-model="description"
     />
     <div class="flex flex-row justify-center">
       <span
@@ -62,9 +62,9 @@
         <font-awesome icon="chevron-left" />
       </div>
       <input
+        v-model="amountInput"
         type="number"
         class="border border-r-0 border-slate-400 px-2 py-2 text-center w-20"
-        v-model="amountInput"
       />
       <div
         class="rounded-r border border-slate-400 bg-slate-200 px-4 py-2"
@@ -81,8 +81,8 @@
         </a>
         <font-awesome
           icon="trash-can"
-          @click="confirmDeleteImage"
           class="text-red-500 fa-fw ml-8 mt-10"
+          @click="confirmDeleteImage"
         />
       </span>
       <span v-else>
@@ -101,9 +101,9 @@
         <div class="flex">
           <input
             v-if="giverDid && !providedByProject"
+            v-model="providedByGiver"
             type="checkbox"
             class="h-6 w-6 mr-2"
-            v-model="providedByGiver"
           />
           <font-awesome
             v-else
@@ -128,9 +128,9 @@
         <div class="flex">
           <input
             v-if="providerProjectId && !providedByGiver"
+            v-model="providedByProject"
             type="checkbox"
             class="h-6 w-6 mr-2"
-            v-model="providedByProject"
           />
           <font-awesome
             v-else
@@ -162,9 +162,9 @@
         <div class="flex">
           <input
             v-if="recipientDid && !givenToProject"
+            v-model="givenToRecipient"
             type="checkbox"
             class="h-6 w-6 mr-2"
-            v-model="givenToRecipient"
           />
           <font-awesome
             v-else
@@ -189,9 +189,9 @@
         <div class="flex">
           <input
             v-if="fulfillsProjectId && !givenToRecipient"
+            v-model="givenToProject"
             type="checkbox"
             class="h-6 w-6 mr-2"
-            v-model="givenToProject"
           />
           <font-awesome
             v-else
@@ -216,7 +216,7 @@
     </div>
 
     <div class="mt-8 flex">
-      <input type="checkbox" class="h-6 w-6 mr-2" v-model="isTrade" />
+      <input v-model="isTrade" type="checkbox" class="h-6 w-6 mr-2" />
       <label class="text-sm mt-1">This was a trade (not a gift)</label>
     </div>
 
diff --git a/src/views/HelpNotificationsView.vue b/src/views/HelpNotificationsView.vue
index c0279866..0ecbfdac 100644
--- a/src/views/HelpNotificationsView.vue
+++ b/src/views/HelpNotificationsView.vue
@@ -30,8 +30,8 @@
         <p>
           If this works then you're all set.
           <button
-            @click="sendTestWebPushMessage(true)"
             class="block w-full text-center text-md bg-gradient-to-b from-slate-400 to-slate-700 shadow-[inset_0_-1px_0_0_rgba(0,0,0,0.5)] text-white px-1.5 py-2 rounded-md mb-2"
+            @click="sendTestWebPushMessage(true)"
           >
             Send Yourself a Test Web Push Message (Through Push Server but
             Skipping Client Filter)
@@ -246,8 +246,8 @@
 
       <h2 class="text-xl font-semibold mt-4">Tests</h2>
       <button
-        @click="showTestNotification()"
         class="block w-full text-center text-md bg-gradient-to-b from-slate-400 to-slate-700 shadow-[inset_0_-1px_0_0_rgba(0,0,0,0.5)] text-white px-1.5 py-2 rounded-md mt-4 mb-2"
+        @click="showTestNotification()"
       >
         Send Test Notification Directly to Device (Not Through Push Server)
       </button>
@@ -259,8 +259,8 @@
       </p>
 
       <button
-        @click="alertWebPushSubscription()"
         class="block w-full text-center text-md bg-gradient-to-b from-slate-400 to-slate-700 shadow-[inset_0_-1px_0_0_rgba(0,0,0,0.5)] text-white px-1.5 py-2 rounded-md mt-4 mb-2"
+        @click="alertWebPushSubscription()"
       >
         Show Web Push Subscription Info
       </button>
@@ -272,8 +272,8 @@
       </p>
 
       <button
-        @click="sendTestWebPushMessage(true)"
         class="block w-full text-center text-md bg-gradient-to-b from-slate-400 to-slate-700 shadow-[inset_0_-1px_0_0_rgba(0,0,0,0.5)] text-white px-1.5 py-2 rounded-md mt-4 mb-2"
+        @click="sendTestWebPushMessage(true)"
       >
         Send Yourself a Test Web Push Message (Through Push Server but Skipping
         Client Filter)
@@ -285,8 +285,8 @@
       </p>
 
       <button
-        @click="sendTestWebPushMessage()"
         class="block w-full text-center text-md bg-gradient-to-b from-slate-400 to-slate-700 shadow-[inset_0_-1px_0_0_rgba(0,0,0,0.5)] text-white px-1.5 py-2 rounded-md mt-4 mb-2"
+        @click="sendTestWebPushMessage()"
       >
         Send Yourself a Test Web Push Message (Through Push Server and Client
         Filter)
diff --git a/src/views/HelpView.vue b/src/views/HelpView.vue
index efc3edc9..fe4d9555 100644
--- a/src/views/HelpView.vue
+++ b/src/views/HelpView.vue
@@ -30,8 +30,8 @@
       <p class="ml-4">
         If you'd like to see the page-by-page help,
         <span
-          @click="unsetFinishedOnboarding()"
           class="text-blue-500 cursor-pointer"
+          @click="unsetFinishedOnboarding()"
         >click here</span>.
       </p>
 
@@ -61,7 +61,7 @@
       <h2 class="text-xl font-semibold">I want to know more because...</h2>
       <ul class="list-disc list-outside ml-4">
         <li class="p-2">
-          <div @click="showAlpha = !showAlpha" class="text-blue-500">... I'm a member of Alpha chat.</div>
+          <div class="text-blue-500" @click="showAlpha = !showAlpha">... I'm a member of Alpha chat.</div>
           <div v-if="showAlpha">
             <p>
               This is a project for public benefit. You are invited to add your gratitude
@@ -98,7 +98,7 @@
           </div>
         </li>
         <li class="p-2">
-          <div @click="showGroup = !showGroup" class="text-blue-500">... I want to find a group I'll enjoy working with.</div>
+          <div class="text-blue-500" @click="showGroup = !showGroup">... I want to find a group I'll enjoy working with.</div>
           <div v-if="showGroup">
             <p>
               This app encourages people to offer small bits of time to one another. It's a way to
@@ -114,7 +114,7 @@
           </div>
         </li>
         <li class="p-2">
-          <div @click="showCommunity = !showCommunity" class="text-blue-500">... I want to participate in community projects.</div>
+          <div class="text-blue-500" @click="showCommunity = !showCommunity">... I want to participate in community projects.</div>
           <div v-if="showCommunity">
             <p>
               These are mostly at the beginning stages, so any of them will appreciate your offers that show interest.
@@ -127,7 +127,7 @@
           </div>
         </li>
         <li class="p-2">
-          <div @click="showVerifiable = !showVerifiable" class="text-blue-500">... I want to build with verifiable, private data.</div>
+          <div class="text-blue-500" @click="showVerifiable = !showVerifiable">... I want to build with verifiable, private data.</div>
           <div v-if="showVerifiable">
             <p>
               Make your claims and get others to confirm them. Then you can use the API to pull your copy of all that
@@ -153,7 +153,7 @@
           </div>
         </li>
         <li class="p-2">
-          <div @click="showGovernance = !showGovernance" class="text-blue-500">... I want to build governance organically.</div>
+          <div class="text-blue-500" @click="showGovernance = !showGovernance">... I want to build governance organically.</div>
           <div v-if="showGovernance">
             <p>
               This requires motivated, dedicated citizens. The good thing is that dedication the primary ingredient;
@@ -172,7 +172,7 @@
           </div>
         </li>
         <li class="p-2">
-          <div @click="showBasics = !showBasics" class="text-blue-500">... I want to supply life's basics freely.</div>
+          <div class="text-blue-500" @click="showBasics = !showBasics">... I want to supply life's basics freely.</div>
           <div v-if="showBasics">
             <p>
               This platform is not optimal for balancing needs and resources at this point,
@@ -529,13 +529,13 @@
         If you have skills, contact us below.
         If you have Bitcoin, donate to
         <button
+          class="text-blue-500 ml-2"
           @click="
             doCopyTwoSecRedo(
               'bc1q90v4ted6cpt63tjfh2lvd5xzfc67sd4g9w8xma',
               () => (showDidCopy = !showDidCopy)
             )
           "
-          class="text-blue-500 ml-2"
         >
           bc1q90v4ted6cpt63tjfh2lvd5xzfc67sd4g9w8xma
           <font-awesome v-show="!showDidCopy" icon="copy" class="text-sm text-slate-400 fa-fw" />
diff --git a/src/views/HomeView.vue b/src/views/HomeView.vue
index d7336fcb..aa43e330 100644
--- a/src/views/HomeView.vue
+++ b/src/views/HomeView.vue
@@ -87,8 +87,8 @@
             To share, someone must register you.
             <div class="block text-center">
               <button
-                @click="showNameThenIdDialog()"
                 class="text-md font-bold bg-gradient-to-b from-blue-400 to-blue-700 shadow-[inset_0_-1px_0_0_rgba(0,0,0,0.5)] text-white mt-2 px-2 py-3 rounded-md"
+                @click="showNameThenIdDialog()"
               >
                 Show them {{ PASSKEYS_ENABLED ? "default" : "your" }} identifier
                 info
@@ -112,8 +112,8 @@
             <div class="flex">
               <h2 class="text-xl font-bold">What have you seen someone do?</h2>
               <button
-                @click="openGiftedPrompts()"
                 class="ml-2 block text-xs text-center bg-gradient-to-b from-slate-400 to-slate-700 shadow-[inset_0_-1px_0_0_rgba(0,0,0,0.5)] text-white px-1 rounded-md"
+                @click="openGiftedPrompts()"
               >
                 <font-awesome icon="lightbulb" class="fa-fw" />
               </button>
@@ -143,7 +143,7 @@
               >
                 <EntityIcon
                   :contact="contact"
-                  :iconSize="64"
+                  :icon-size="64"
                   class="mx-auto border border-blue-500 rounded-md mb-1 cursor-pointer"
                 />
                 <h3
@@ -204,8 +204,8 @@
       </div>
 
       <div
-        @click="goToActivityToUserPage()"
         class="border-t p-2 border-slate-300"
+        @click="goToActivityToUserPage()"
       >
         <div class="flex justify-center">
           <div
@@ -247,13 +247,13 @@
       <InfiniteScroll @reached-bottom="loadMoreGives">
         <ul id="listLatestActivity" class="border-t border-slate-300">
           <li
-            class="border-b border-slate-300 py-2"
             v-for="record in feedData"
             :key="record.jwtId"
+            class="border-b border-slate-300 py-2"
           >
             <div
-              class="border-b border-slate-300 text-orange-400 pb-2 mb-2 font-bold text-sm"
               v-if="record.jwtId == feedLastViewedClaimId"
+              class="border-b border-slate-300 text-orange-400 pb-2 mb-2 font-bold text-sm"
             >
               You've already seen all the following
             </div>
@@ -374,9 +374,9 @@
   <ChoiceButtonDialog ref="choiceButtonDialog" />
 
   <ImageViewer
+    v-model:is-open="isImageViewerOpen"
     :image-url="selectedImage"
     :image-data="selectedImageData"
-    v-model:is-open="isImageViewerOpen"
   />
 </template>
 
diff --git a/src/views/ImportAccountView.vue b/src/views/ImportAccountView.vue
index 328adc69..5514d589 100644
--- a/src/views/ImportAccountView.vue
+++ b/src/views/ImportAccountView.vue
@@ -5,8 +5,8 @@
       <h1 class="text-lg text-center font-light relative px-7">
         <!-- Cancel -->
         <button
-          @click="$router.go(-1)"
           class="text-lg text-center px-2 py-1 absolute -left-2 -top-1"
+          @click="$router.go(-1)"
         >
           <font-awesome icon="chevron-left"></font-awesome>
         </button>
@@ -20,10 +20,10 @@
     <!-- id used by puppeteer test script -->
     <textarea
       id="seed-input"
+      v-model="mnemonic"
       type="text"
       placeholder="Seed Phrase"
       class="block w-full rounded border border-slate-400 mb-4 px-3 py-2"
-      v-model="mnemonic"
     />
 
     <h3
@@ -35,22 +35,22 @@
     <div v-if="showAdvanced">
       Enter a custom derivation path
       <input
+        v-model="derivationPath"
         type="text"
         class="block w-full rounded border border-slate-400 mb-2 px-3 py-2"
-        v-model="derivationPath"
       />
       <span class="ml-4">
         For previous uPort or Endorser users,
         <a
-          @click="derivationPath = UPORT_DERIVATION_PATH"
           class="text-blue-500"
+          @click="derivationPath = UPORT_DERIVATION_PATH"
         >
           click here to use that value.
         </a>
       </span>
 
-      <div class="mt-4" v-if="numAccounts == 1">
-        <input type="checkbox" class="mr-2" v-model="shouldErase" />
+      <div v-if="numAccounts == 1" class="mt-4">
+        <input v-model="shouldErase" type="checkbox" class="mr-2" />
         <label>Erase the previous identifier.</label>
       </div>
 
@@ -65,15 +65,15 @@
     <div class="mt-8">
       <div class="grid grid-cols-1 sm:grid-cols-2 gap-2">
         <button
-          @click="fromMnemonic()"
           class="block w-full text-center text-lg font-bold uppercase bg-gradient-to-b from-blue-400 to-blue-700 shadow-[inset_0_-1px_0_0_rgba(0,0,0,0.5)] text-white px-2 py-3 rounded-md"
+          @click="fromMnemonic()"
         >
           Import
         </button>
         <button
-          @click="onCancelClick()"
           type="button"
           class="block w-full text-center text-md uppercase bg-gradient-to-b from-slate-400 to-slate-700 shadow-[inset_0_-1px_0_0_rgba(0,0,0,0.5)] text-white px-1.5 py-2 rounded-md"
+          @click="onCancelClick()"
         >
           Cancel
         </button>
diff --git a/src/views/ImportDerivedAccountView.vue b/src/views/ImportDerivedAccountView.vue
index bb465155..7803350e 100644
--- a/src/views/ImportDerivedAccountView.vue
+++ b/src/views/ImportDerivedAccountView.vue
@@ -5,8 +5,8 @@
       <h1 class="text-lg text-center font-light relative px-7">
         <!-- Cancel -->
         <button
-          @click="$router.go(-1)"
           class="text-lg text-center px-2 py-1 absolute -left-2 -top-1"
+          @click="$router.go(-1)"
         >
           <font-awesome icon="chevron-left"></font-awesome>
         </button>
@@ -25,9 +25,9 @@
       </p>
       <ul class="mb-4">
         <li
-          class="block bg-slate-100 rounded-md flex items-center px-4 py-3 mb-2"
           v-for="dids in didArrays"
           :key="dids[0]"
+          class="block bg-slate-100 rounded-md flex items-center px-4 py-3 mb-2"
           @click="switchAccount(dids[0])"
         >
           <font-awesome
@@ -51,15 +51,15 @@
     <div class="mt-8">
       <div class="grid grid-cols-1 sm:grid-cols-2 gap-2">
         <button
-          @click="incrementDerivation()"
           class="block w-full text-center text-lg font-bold uppercase bg-gradient-to-b from-blue-400 to-blue-700 shadow-[inset_0_-1px_0_0_rgba(0,0,0,0.5)] text-white px-2 py-3 rounded-md"
+          @click="incrementDerivation()"
         >
           Increment and Import
         </button>
         <button
-          @click="onCancelClick()"
           type="button"
           class="block w-full text-center text-md uppercase bg-gradient-to-b from-slate-400 to-slate-700 shadow-[inset_0_-1px_0_0_rgba(0,0,0,0.5)] text-white px-1.5 py-2 rounded-md"
+          @click="onCancelClick()"
         >
           Cancel
         </button>
diff --git a/src/views/InviteOneAcceptView.vue b/src/views/InviteOneAcceptView.vue
index d8aea4dc..e9188b19 100644
--- a/src/views/InviteOneAcceptView.vue
+++ b/src/views/InviteOneAcceptView.vue
@@ -28,8 +28,8 @@
       />
       <br />
       <button
-        @click="() => processInvite(inputJwt, true)"
         class="ml-2 p-2 bg-blue-500 text-white rounded"
+        @click="() => processInvite(inputJwt, true)"
       >
         Accept
       </button>
diff --git a/src/views/InviteOneView.vue b/src/views/InviteOneView.vue
index 9acb782a..efe0ddd3 100644
--- a/src/views/InviteOneView.vue
+++ b/src/views/InviteOneView.vue
@@ -72,16 +72,18 @@
                   !invite.redeemedAt &&
                   invite.expiresAt > new Date().toISOString()
                 "
+                class="text-center text-blue-500 cursor-pointer"
+                :title="inviteLink(invite.jwt)"
                 @click="
                   copyInviteAndNotify(invite.inviteIdentifier, invite.jwt)
                 "
-                class="text-center text-blue-500 cursor-pointer"
-                :title="inviteLink(invite.jwt)"
               >
                 {{ getTruncatedInviteId(invite.inviteIdentifier) }}
               </span>
               <span
                 v-else
+                class="text-center text-slate-500 cursor-pointer"
+                :title="inviteLink(invite.jwt)"
                 @click="
                   showInvite(
                     invite.inviteIdentifier,
@@ -89,8 +91,6 @@
                     invite.expiresAt < new Date().toISOString(),
                   )
                 "
-                class="text-center text-slate-500 cursor-pointer"
-                :title="inviteLink(invite.jwt)"
               >
                 {{ getTruncatedInviteId(invite.inviteIdentifier) }}
               </span>
diff --git a/src/views/NewActivityView.vue b/src/views/NewActivityView.vue
index a6b4e1f4..54718fe7 100644
--- a/src/views/NewActivityView.vue
+++ b/src/views/NewActivityView.vue
@@ -8,8 +8,8 @@
         <!-- Back -->
         <font-awesome
           icon="chevron-left"
-          @click="$router.back()"
           class="fa-fw text-lg text-center px-2 py-1 absolute -left-2 -top-1"
+          @click="$router.back()"
         />
         New Activity For You
       </h1>
@@ -66,8 +66,8 @@
           </router-link>
           <!-- New line that appears on hover or when the offer is clicked -->
           <div
-            @click="markOffersAsReadStartingWith(offer.jwtId)"
             class="absolute left-0 w-full text-left text-gray-500 text-sm hidden group-hover:flex cursor-pointer items-center"
+            @click="markOffersAsReadStartingWith(offer.jwtId)"
           >
             <span class="inline-block w-8 h-px bg-gray-500 mr-2" />
             Click to keep all above as new offers
@@ -135,8 +135,8 @@
           </router-link>
           <!-- New line that appears on hover -->
           <div
-            @click="markOffersToUserProjectsAsReadStartingWith(offer.jwtId)"
             class="absolute left-0 w-full text-left text-gray-500 text-sm hidden group-hover:flex cursor-pointer items-center"
+            @click="markOffersToUserProjectsAsReadStartingWith(offer.jwtId)"
           >
             <span class="inline-block w-8 h-px bg-gray-500 mr-2" />
             Click to keep all above as new offers
diff --git a/src/views/NewEditAccountView.vue b/src/views/NewEditAccountView.vue
index fa5cae73..2c2deaa9 100644
--- a/src/views/NewEditAccountView.vue
+++ b/src/views/NewEditAccountView.vue
@@ -5,8 +5,8 @@
       <h1 class="text-lg text-center font-light relative px-7">
         <!-- Cancel -->
         <button
-          @click="$router.back()"
           class="text-lg text-center px-2 py-1 absolute -left-2 -top-1"
+          @click="$router.back()"
         >
           <font-awesome icon="chevron-left" class="fa-fw"></font-awesome>
         </button>
@@ -15,10 +15,10 @@
     </div>
 
     <input
+      v-model="givenName"
       type="text"
       placeholder="Name"
       class="block w-full rounded border border-slate-400 mb-4 px-3 py-2"
-      v-model="givenName"
     />
 
     <div class="mt-8">
diff --git a/src/views/NewEditProjectView.vue b/src/views/NewEditProjectView.vue
index 9beded74..c27db1dd 100644
--- a/src/views/NewEditProjectView.vue
+++ b/src/views/NewEditProjectView.vue
@@ -8,8 +8,8 @@
         <!-- Cancel -->
         <!-- Back -->
         <button
-          @click="$router.back()"
           class="text-lg text-center px-2 py-1 absolute -left-2 -top-1"
+          @click="$router.back()"
         >
           <font-awesome icon="chevron-left" class="fa-fw"></font-awesome>
         </button>
@@ -25,10 +25,10 @@
     </div>
 
     <input
+      v-model="fullClaim.name"
       type="text"
       placeholder="Idea Name"
       class="block w-full rounded border border-slate-400 mb-4 px-3 py-2"
-      v-model="fullClaim.name"
     />
 
     <div class="flex justify-center mt-4">
@@ -38,8 +38,8 @@
         </a>
         <font-awesome
           icon="trash-can"
-          @click="confirmDeleteImage"
           class="text-red-500 fa-fw ml-8 mt-10"
+          @click="confirmDeleteImage"
         />
       </span>
       <span v-else>
@@ -53,27 +53,27 @@
     <ImageMethodDialog ref="imageDialog" />
 
     <input
+      v-model="agentDid"
       type="text"
       placeholder="Other Authorized Representative"
       class="mt-4 block w-full rounded border border-slate-400 px-3 py-2"
-      v-model="agentDid"
     />
     <div class="mb-4">
       <p v-if="activeDid != projectIssuerDid && agentDid != projectIssuerDid">
         <span class="text-red-500">Beware!</span>
         If you save this, the original project owner will no longer be able to
         edit it.
-        <button @click="agentDid = projectIssuerDid" class="text-blue-500">
+        <button class="text-blue-500" @click="agentDid = projectIssuerDid">
           Click here to make the original owner an authorized representative.
         </button>
       </p>
     </div>
 
     <textarea
+      v-model="fullClaim.description"
       placeholder="Description"
       class="block w-full rounded border border-slate-400 px-3 py-2"
       rows="5"
-      v-model="fullClaim.description"
       maxlength="5000"
     ></textarea>
     <div class="text-xs text-slate-500 italic">
@@ -102,9 +102,9 @@
           class="rounded border border-slate-400 px-3 py-2"
         />
         <input
+          v-model="startTimeInput"
           :disabled="!startDateInput"
           placeholder="Start Time"
-          v-model="startTimeInput"
           type="time"
           class="rounded border border-slate-400 ml-2 px-3 py-2"
         />
@@ -127,9 +127,9 @@
           class="ml-2 rounded border border-slate-400 px-3 py-2"
         />
         <input
+          v-model="endTimeInput"
           :disabled="!endDateInput"
           placeholder="End Time"
-          v-model="endTimeInput"
           type="time"
           class="rounded border border-slate-400 ml-2 px-3 py-2"
         />
@@ -140,7 +140,7 @@
       class="flex items-center mt-4"
       @click="includeLocation = !includeLocation"
     >
-      <input type="checkbox" class="mr-2" v-model="includeLocation" />
+      <input v-model="includeLocation" type="checkbox" class="mr-2" />
       <label for="includeLocation">Include Location</label>
     </div>
     <div v-if="includeLocation" class="mb-4 aspect-video">
@@ -179,7 +179,7 @@
       class="items-center mb-4"
     >
       <div class="flex" @click="sendToTrustroots = !sendToTrustroots">
-        <input type="checkbox" class="mr-2" v-model="sendToTrustroots" />
+        <input v-model="sendToTrustroots" type="checkbox" class="mr-2" />
         <label>Send to Trustroots</label>
         <font-awesome
           icon="circle-info"
diff --git a/src/views/OfferDetailsView.vue b/src/views/OfferDetailsView.vue
index c2086807..4d8592f5 100644
--- a/src/views/OfferDetailsView.vue
+++ b/src/views/OfferDetailsView.vue
@@ -33,9 +33,9 @@
       >
     </h1>
     <textarea
+      v-model="descriptionOfItem"
       class="block w-full rounded border border-slate-400 mb-2 px-3 py-2"
       placeholder="What is offered"
-      v-model="descriptionOfItem"
       data-testId="itemDescription"
     />
     <div class="flex flex-row justify-center">
@@ -52,9 +52,9 @@
         <font-awesome icon="chevron-left" />
       </div>
       <input
+        v-model="amountInput"
         type="number"
         class="border border-r-0 border-slate-400 px-2 py-2 text-center w-20"
-        v-model="amountInput"
         data-testId="inputOfferAmount"
       />
       <div
@@ -72,9 +72,9 @@
         Conditions
       </span>
       <textarea
+        v-model="descriptionOfCondition"
         class="w-full border border-slate-400 px-3 py-2 rounded-r"
         placeholder="Prerequisites, other people to include, etc."
-        v-model="descriptionOfCondition"
       />
     </div>
 
@@ -94,9 +94,9 @@
     <div class="h-7 mt-4 flex">
       <input
         v-if="projectId && !offeredToRecipient"
+        v-model="offeredToProject"
         type="checkbox"
         class="h-6 w-6 mr-2"
-        v-model="offeredToProject"
       />
       <font-awesome
         v-else
@@ -116,9 +116,9 @@
     <div class="h-7 mt-4 flex">
       <input
         v-if="recipientDid && !offeredToProject"
+        v-model="offeredToRecipient"
         type="checkbox"
         class="h-6 w-6 mr-2"
-        v-model="offeredToRecipient"
       />
       <font-awesome
         v-else
diff --git a/src/views/OnboardMeetingListView.vue b/src/views/OnboardMeetingListView.vue
index 3531815f..7fbcc80a 100644
--- a/src/views/OnboardMeetingListView.vue
+++ b/src/views/OnboardMeetingListView.vue
@@ -22,9 +22,9 @@
         <div class="flex justify-between items-center">
           <h2 class="text-xl font-medium">{{ attendingMeeting.name }}</h2>
           <button
-            @click.stop="leaveMeeting"
             class="text-red-600 hover:text-red-700 p-2"
             title="Leave Meeting"
+            @click.stop="leaveMeeting"
           >
             <font-awesome icon="right-from-bracket" />
           </button>
@@ -65,14 +65,14 @@
         />
         <div class="flex justify-end space-x-4">
           <button
-            @click="cancelPasswordDialog"
             class="px-4 py-2 bg-gray-200 rounded hover:bg-gray-300"
+            @click="cancelPasswordDialog"
           >
             Cancel
           </button>
           <button
-            @click="submitPassword"
             class="px-4 py-2 bg-blue-600 text-white rounded hover:bg-blue-700"
+            @click="submitPassword"
           >
             Submit
           </button>
diff --git a/src/views/OnboardMeetingMembersView.vue b/src/views/OnboardMeetingMembersView.vue
index f0992f42..ff963d50 100644
--- a/src/views/OnboardMeetingMembersView.vue
+++ b/src/views/OnboardMeetingMembersView.vue
@@ -10,8 +10,8 @@
 
     <!-- Loading Animation -->
     <div
-      class="mt-16 text-center text-4xl bg-slate-400 text-white w-14 py-2.5 rounded-full mx-auto"
       v-if="isLoading"
+      class="mt-16 text-center text-4xl bg-slate-400 text-white w-14 py-2.5 rounded-full mx-auto"
     >
       <font-awesome icon="spinner" class="fa-spin-pulse"></font-awesome>
     </div>
diff --git a/src/views/OnboardMeetingSetupView.vue b/src/views/OnboardMeetingSetupView.vue
index 3bfb8cee..ac0d8635 100644
--- a/src/views/OnboardMeetingSetupView.vue
+++ b/src/views/OnboardMeetingSetupView.vue
@@ -17,9 +17,9 @@
         <div class="flex items-center">
           <h2 class="text-2xl">Current Meeting</h2>
           <button
-            @click="startEditing"
             class="mb-4 text-blue-600 hover:text-blue-800 transition-colors duration-200 ml-2"
             title="Edit Meeting"
+            @click="startEditing"
           >
             <font-awesome icon="pen" class="fa-fw" />
             <span class="sr-only">{{
@@ -28,11 +28,11 @@
           </button>
         </div>
         <button
-          @click="confirmDelete"
           class="text-red-600 hover:text-red-800 transition-colors duration-200"
           :disabled="isDeleting"
           :class="{ 'opacity-50 cursor-not-allowed': isDeleting }"
           title="Delete Meeting"
+          @click="confirmDelete"
         >
           <font-awesome icon="trash-can" class="fa-fw" />
           <span class="sr-only">{{
@@ -72,14 +72,14 @@
         </p>
         <div class="flex justify-between space-x-4">
           <button
-            @click="showDeleteConfirm = false"
             class="px-4 py-2 bg-slate-500 text-white rounded hover:bg-slate-700"
+            @click="showDeleteConfirm = false"
           >
             Cancel
           </button>
           <button
-            @click="deleteMeeting"
             class="px-4 py-2 bg-red-600 text-white rounded hover:bg-red-700"
+            @click="deleteMeeting"
           >
             Delete
           </button>
@@ -101,8 +101,8 @@
       </h2>
       <!-- This is my first form. Not sure if I like it; will see if the browser benefits extend to the native app. -->
       <form
-        @submit.prevent="isInCreateMode() ? createMeeting() : updateMeeting()"
         class="space-y-4"
+        @submit.prevent="isInCreateMode() ? createMeeting() : updateMeeting()"
       >
         <div>
           <label
@@ -182,8 +182,8 @@
         <button
           v-if="isInEditOrCreateMode()"
           type="button"
-          @click="cancelEditing"
           class="w-full bg-slate-500 text-white px-4 py-2 rounded-md hover:bg-slate-600"
+          @click="cancelEditing"
         >
           Cancel
         </button>
@@ -211,8 +211,8 @@
       <MembersList
         :password="currentMeeting.password || ''"
         :show-organizer-tools="true"
-        @error="handleMembersError"
         class="mt-4"
+        @error="handleMembersError"
       />
     </div>
 
diff --git a/src/views/ProjectViewView.vue b/src/views/ProjectViewView.vue
index 46bf9c08..97262994 100644
--- a/src/views/ProjectViewView.vue
+++ b/src/views/ProjectViewView.vue
@@ -10,8 +10,8 @@
         <h1 class="text-center text-lg font-light relative px-7">
           <!-- Back -->
           <button
-            @click="$router.back()"
             class="text-lg text-center px-2 py-1 absolute -left-2 -top-1"
+            @click="$router.back()"
           >
             <font-awesome icon="chevron-left" class="fa-fw"></font-awesome>
           </button>
@@ -21,9 +21,9 @@
           {{ name }}
           <button
             v-if="activeDid === issuer || activeDid === agentDid"
-            @click="onEditClick()"
             title="Edit"
             data-testId="editClaimButton"
+            @click="onEditClick()"
           >
             <font-awesome icon="pen" class="text-sm text-blue-500 ml-2 mb-1" />
           </button>
@@ -37,10 +37,10 @@
         <div class="pb-4 flex gap-4">
           <div class="pt-1">
             <ProjectIcon
-              :entityId="projectId"
-              :iconSize="64"
-              :imageUrl="imageUrl"
-              :linkToFull="true"
+              :entity-id="projectId"
+              :icon-size="64"
+              :image-url="imageUrl"
+              :link-to-full="true"
               class="block border border-slate-300 rounded-md max-h-16 max-w-16"
             />
           </div>
@@ -113,7 +113,7 @@
                   target="_blank"
                   class="underline text-blue-500"
                 >
-                  {{ domainForWebsite(this.url) }}
+                  {{ domainForWebsite(url) }}
                   <font-awesome
                     icon="arrow-up-right-from-square"
                     class="fa-fw"
@@ -129,22 +129,22 @@
             {{ truncatedDesc }}
             <a
               v-if="description.length >= truncateLength"
-              @click="expandText"
               class="uppercase text-xs font-semibold text-slate-700"
+              @click="expandText"
               >... Read More</a
             >
           </div>
           <div v-else>
             {{ description }}
             <a
-              @click="collapseText"
               class="uppercase text-xs font-semibold text-slate-700"
+              @click="collapseText"
               >- Read Less</a
             >
           </div>
         </div>
 
-        <a @click="onClickLoadClaim(projectId)" class="cursor-pointer">
+        <a class="cursor-pointer" @click="onClickLoadClaim(projectId)">
           <font-awesome icon="file-lines" class="pl-2 pt-1 text-blue-500" />
         </a>
       </div>
@@ -163,8 +163,8 @@
           <div class="text-center">
             <div v-for="plan in fulfillersToThis" :key="plan.handleId">
               <button
-                @click="onClickLoadProject(plan.handleId)"
                 class="text-blue-500"
+                @click="onClickLoadProject(plan.handleId)"
               >
                 {{ plan.name }}
               </button>
@@ -184,8 +184,8 @@
           <!-- centering because long, wrapped project names didn't left align with blank or "text-left" -->
           <div class="text-center">
             <button
-              @click="onClickLoadProject(fulfilledByThis.handleId)"
               class="text-blue-500"
+              @click="onClickLoadProject(fulfilledByThis.handleId)"
             >
               {{ fulfilledByThis.name }}
             </button>
@@ -230,7 +230,7 @@
         >
           <EntityIcon
             :contact="contact"
-            :iconSize="64"
+            :icon-size="64"
             class="mx-auto border border-blue-300 rounded-md mb-1 cursor-pointer"
           />
           <h3
@@ -242,14 +242,14 @@
         <li>
           <span
             v-if="allContacts.length >= 5"
-            @click="onClickAllContactsGifting()"
             class="flex align-bottom text-xs text-blue-500 mt-12 cursor-pointer"
+            @click="onClickAllContactsGifting()"
           >
             ... or someone else...
           </span>
         </li>
       </ul>
-      <GiftedDialog ref="giveDialogToThis" :toProjectId="this.projectId" />
+      <GiftedDialog ref="giveDialogToThis" :to-project-id="projectId" />
     </div>
 
     <!-- Offers & Gifts to & from this -->
@@ -260,8 +260,8 @@
           <div class="text-center">
             <button
               data-testId="offerButton"
-              @click="openOfferDialog()"
               class="block w-full bg-gradient-to-b from-blue-400 to-blue-700 shadow-[inset_0_-1px_0_0_rgba(0,0,0,0.5)] text-white px-1 rounded-md"
+              @click="openOfferDialog()"
             >
               Offer to this (maybe with conditions)...
             </button>
@@ -269,15 +269,15 @@
         </div>
         <OfferDialog
           ref="customOfferDialog"
-          :projectId="this.projectId"
-          :projectName="this.name"
+          :project-id="projectId"
+          :project-name="name"
         />
 
         <h3 class="text-lg font-bold mb-3 mt-4">Offered To This Idea</h3>
 
         <div v-if="offersToThis.length === 0">
           (None yet. Wanna
-          <span @click="openOfferDialog()" class="cursor-pointer text-blue-500"
+          <span class="cursor-pointer text-blue-500" @click="openOfferDialog()"
             >offer something... especially if others join you</span
           >?)
         </div>
@@ -316,8 +316,8 @@
             </div>
             <div class="flex justify-between">
               <a
-                @click="onClickLoadClaim(offer.jwtId as string)"
                 class="cursor-pointer"
+                @click="onClickLoadClaim(offer.jwtId as string)"
               >
                 <font-awesome
                   icon="file-lines"
@@ -347,8 +347,8 @@
         <div v-if="activeDid && isRegistered">
           <div class="text-center">
             <button
-              @click="openGiftDialogToProject()"
               class="block w-full bg-gradient-to-b from-blue-400 to-blue-700 shadow-[inset_0_-1px_0_0_rgba(0,0,0,0.5)] text-white px-1rounded-md"
+              @click="openGiftDialogToProject()"
             >
               Given To This...
             </button>
@@ -443,17 +443,14 @@
         <div v-if="activeDid && isRegistered">
           <div class="text-center">
             <button
-              @click="openGiftDialogFromProject()"
               class="block w-full bg-gradient-to-b from-blue-400 to-blue-700 shadow-[inset_0_-1px_0_0_rgba(0,0,0,0.5)] text-white px-1 rounded-md"
+              @click="openGiftDialogFromProject()"
             >
               Given By This...
             </button>
           </div>
         </div>
-        <GiftedDialog
-          ref="giveDialogFromThis"
-          :fromProjectId="this.projectId"
-        />
+        <GiftedDialog ref="giveDialogFromThis" :from-project-id="projectId" />
 
         <h3 class="text-lg font-bold mb-3 mt-4">
           Benefitted From This Project
diff --git a/src/views/ProjectsView.vue b/src/views/ProjectsView.vue
index 0b466a07..37a7dbe4 100644
--- a/src/views/ProjectsView.vue
+++ b/src/views/ProjectsView.vue
@@ -16,6 +16,7 @@
         <li>
           <a
             href="#"
+            :class="computedOfferTabClassNames()"
             @click="
               offers = [];
               projects = [];
@@ -23,7 +24,6 @@
               showProjects = false;
               loadOffers();
             "
-            v-bind:class="computedOfferTabClassNames()"
           >
             Offers
           </a>
@@ -31,6 +31,7 @@
         <li>
           <a
             href="#"
+            :class="computedProjectTabClassNames()"
             @click="
               offers = [];
               projects = [];
@@ -38,7 +39,6 @@
               showProjects = true;
               loadProjects();
             "
-            v-bind:class="computedProjectTabClassNames()"
           >
             Projects
           </a>
@@ -73,8 +73,8 @@
 
     <!-- Loading Animation -->
     <div
-      class="fixed left-6 bottom-24 text-center text-4xl leading-none bg-slate-400 text-white w-14 py-2.5 rounded-full"
       v-if="isLoading"
+      class="fixed left-6 bottom-24 text-center text-4xl leading-none bg-slate-400 text-white w-14 py-2.5 rounded-full"
     >
       <font-awesome icon="spinner" class="fa-spin-pulse"></font-awesome>
     </div>
@@ -90,22 +90,22 @@
       </div>
       <ul id="listOffers" class="border-t border-slate-300">
         <li
-          class="border-b border-slate-300"
           v-for="offer in offers"
           :key="offer.handleId"
+          class="border-b border-slate-300"
         >
           <div class="block py-4 flex gap-4">
             <div v-if="offer.fulfillsPlanHandleId" class="flex-none">
               <ProjectIcon
-                :entityId="offer.fulfillsPlanHandleId"
-                :iconSize="48"
+                :entity-id="offer.fulfillsPlanHandleId"
+                :icon-size="48"
                 class="inline-block align-middle border border-slate-300 rounded-md max-h-12 max-w-12"
               />
             </div>
             <div v-if="offer.recipientDid" class="flex-none w-12">
               <EntityIcon
-                :entityId="offer.recipientDid"
-                :iconSize="48"
+                :entity-id="offer.recipientDid"
+                :icon-size="48"
                 class="inline-block align-middle border border-slate-300 rounded-md"
               />
             </div>
@@ -223,8 +223,8 @@
         </div>
         <div v-else>
           <button
-            @click="showNameThenIdDialog()"
             class="text-md font-bold bg-gradient-to-b from-blue-400 to-blue-700 shadow-[inset_0_-1px_0_0_rgba(0,0,0,0.5)] text-white mt-2 px-2 py-3 rounded-md"
+            @click="showNameThenIdDialog()"
           >
             Get someone to onboard you.
           </button>
@@ -233,19 +233,19 @@
       </div>
       <ul id="listProjects" class="border-t border-slate-300">
         <li
-          class="border-b border-slate-300"
           v-for="project in projects"
           :key="project.handleId"
+          class="border-b border-slate-300"
         >
           <a
-            @click="onClickLoadProject(project.handleId)"
             class="block py-4 flex gap-4"
+            @click="onClickLoadProject(project.handleId)"
           >
             <div class="flex-none">
               <ProjectIcon
-                :entityId="project.handleId"
-                :iconSize="48"
-                :imageUrl="project.image"
+                :entity-id="project.handleId"
+                :icon-size="48"
+                :image-url="project.image"
                 class="inline-block align-middle border border-slate-300 rounded-md max-h-12 max-w-12"
               />
             </div>
diff --git a/src/views/QuickActionBvcBeginView.vue b/src/views/QuickActionBvcBeginView.vue
index 70cc9861..601238cf 100644
--- a/src/views/QuickActionBvcBeginView.vue
+++ b/src/views/QuickActionBvcBeginView.vue
@@ -22,17 +22,17 @@
     <div>
       <h2 class="text-2xl m-2">You're Here</h2>
       <div class="m-2 flex">
-        <input type="checkbox" v-model="attended" class="h-6 w-6" />
+        <input v-model="attended" type="checkbox" class="h-6 w-6" />
         <span class="pb-2 pl-2 pr-2">Attended</span>
       </div>
       <div class="m-2 flex">
-        <input type="checkbox" v-model="gaveTime" class="h-6 w-6" />
+        <input v-model="gaveTime" type="checkbox" class="h-6 w-6" />
         <span class="pb-2 pl-2 pr-2">Spent Time</span>
         <span v-if="gaveTime">
           <input
+            v-model="hoursStr"
             type="text"
             placeholder="How much time"
-            v-model="hoursStr"
             size="1"
             class="border border-slate-400 h-6 px-2"
           />
@@ -48,8 +48,8 @@
       class="flex justify-center mt-4"
     >
       <button
-        @click="record()"
         class="block text-center text-md font-bold bg-gradient-to-b from-blue-400 to-blue-700 shadow-[inset_0_-1px_0_0_rgba(0,0,0,0.5)] text-white px-2 py-3 rounded-md w-56"
+        @click="record()"
       >
         Sign & Send
       </button>
diff --git a/src/views/QuickActionBvcEndView.vue b/src/views/QuickActionBvcEndView.vue
index b1bb6a48..b45b6196 100644
--- a/src/views/QuickActionBvcEndView.vue
+++ b/src/views/QuickActionBvcEndView.vue
@@ -29,9 +29,9 @@
       </div>
       <ul class="border-t border-slate-300 m-2">
         <li
-          class="border-b border-slate-300 py-2"
           v-for="record in claimsToConfirm"
           :key="record.id"
+          class="border-b border-slate-300 py-2"
         >
           <div class="grid grid-cols-12">
             <span class="col-span-11 justify-self-start">
@@ -39,6 +39,7 @@
                 <input
                   type="checkbox"
                   :checked="claimsToConfirmSelected.includes(record.id)"
+                  class="mr-2 h-6 w-6"
                   @click="
                     claimsToConfirmSelected.includes(record.id)
                       ? claimsToConfirmSelected.splice(
@@ -47,7 +48,6 @@
                         )
                       : claimsToConfirmSelected.push(record.id)
                   "
-                  class="mr-2 h-6 w-6"
                 />
               </span>
               {{
@@ -96,18 +96,18 @@
     <div>
       <h2 class="text-2xl m-2">Anything else?</h2>
       <div class="m-2 flex">
-        <input type="checkbox" v-model="someoneGave" class="h-6 w-6" />
+        <input v-model="someoneGave" type="checkbox" class="h-6 w-6" />
         <span class="pb-2 pl-2 pr-2">The group provided</span>
         <span v-if="someoneGave">
           <input
-            type="text"
             v-model="description"
+            type="text"
             size="20"
             class="border border-slate-400 h-6 px-2"
           />
           <br />
           (Everyone likes personalized messages! 😁 ... and for a pic:
-          <input type="checkbox" v-model="supplyGiftDetails" />)
+          <input v-model="supplyGiftDetails" type="checkbox" />)
         </span>
         <!-- This is to match input height to avoid shifting when hiding & showing. -->
         <span v-else class="h-6">...</span>
@@ -119,8 +119,8 @@
       class="flex justify-center mt-4"
     >
       <button
-        @click="record()"
         class="block text-center text-md font-bold bg-gradient-to-b from-blue-400 to-blue-700 shadow-[inset_0_-1px_0_0_rgba(0,0,0,0.5)] text-white px-2 py-3 rounded-md w-56"
+        @click="record()"
       >
         Sign & Send
       </button>
diff --git a/src/views/RecentOffersToUserProjectsView.vue b/src/views/RecentOffersToUserProjectsView.vue
index b6da7dd6..4b0d44ec 100644
--- a/src/views/RecentOffersToUserProjectsView.vue
+++ b/src/views/RecentOffersToUserProjectsView.vue
@@ -8,8 +8,8 @@
         <!-- Back -->
         <font-awesome
           icon="chevron-left"
-          @click="$router.back()"
           class="fa-fw text-lg text-center px-2 py-1 absolute -left-2 -top-1"
+          @click="$router.back()"
         />
         Offers to Your Projects
       </h1>
@@ -42,8 +42,8 @@
           class="mt-4 relative group"
         >
           <div
-            class="border-b border-slate-300 text-orange-400 pb-2 mb-2 font-bold text-sm"
             v-if="offer.jwtId == lastAckedOfferToUserProjectsJwtId"
+            class="border-b border-slate-300 text-orange-400 pb-2 mb-2 font-bold text-sm"
           >
             You've already seen all the following
           </div>
diff --git a/src/views/RecentOffersToUserView.vue b/src/views/RecentOffersToUserView.vue
index b1ebcab1..235bd56d 100644
--- a/src/views/RecentOffersToUserView.vue
+++ b/src/views/RecentOffersToUserView.vue
@@ -8,8 +8,8 @@
         <!-- Back -->
         <font-awesome
           icon="chevron-left"
-          @click="$router.back()"
           class="fa-fw text-lg text-center px-2 py-1 absolute -left-2 -top-1"
+          @click="$router.back()"
         />
         Offers to You
       </h1>
@@ -37,8 +37,8 @@
           class="mt-4 relative group"
         >
           <div
-            class="border-b border-slate-300 text-orange-400 pb-2 mb-2 font-bold text-sm"
             v-if="offer.jwtId == lastAckedOfferToUserJwtId"
+            class="border-b border-slate-300 text-orange-400 pb-2 mb-2 font-bold text-sm"
           >
             You've already seen all the following
           </div>
diff --git a/src/views/SearchAreaView.vue b/src/views/SearchAreaView.vue
index 65a2d2d5..84ac95b6 100644
--- a/src/views/SearchAreaView.vue
+++ b/src/views/SearchAreaView.vue
@@ -71,9 +71,9 @@
     <div class="aspect-video">
       <l-map
         ref="map"
+        v-model:zoom="localZoom"
         :center="[localCenterLat, localCenterLong]"
         class="!z-40 rounded-md"
-        v-model:zoom="localZoom"
         @click="setMapPoint"
       >
         <l-tile-layer
diff --git a/src/views/SharedPhotoView.vue b/src/views/SharedPhotoView.vue
index bc8f65bf..c9b2278d 100644
--- a/src/views/SharedPhotoView.vue
+++ b/src/views/SharedPhotoView.vue
@@ -14,22 +14,22 @@
         <div class="text-center mb-4">Choose how to use this image</div>
         <div class="grid grid-cols-1 sm:grid-cols-3 gap-4">
           <button
-            @click="recordGift"
             class="text-center text-md font-bold bg-gradient-to-b from-blue-400 to-blue-700 shadow-[inset_0_-1px_0_0_rgba(0,0,0,0.5)] text-white px-2 py-3 rounded-md"
+            @click="recordGift"
           >
             <font-awesome icon="gift" class="fa-fw" />
             Record a Gift
           </button>
           <button
-            @click="recordProfile"
             class="text-center text-md font-bold bg-gradient-to-b from-blue-400 to-blue-700 shadow-[inset_0_-1px_0_0_rgba(0,0,0,0.5)] text-white px-2 py-3 rounded-md"
+            @click="recordProfile"
           >
             <font-awesome icon="circle-user" class="fa-fw" />
             Save as Profile Image
           </button>
           <button
-            @click="cancel"
             class="text-center text-md font-bold bg-gradient-to-b from-slate-400 to-slate-700 shadow-[inset_0_-1px_0_0_rgba(0,0,0,0.5)] text-white px-2 py-3 rounded-md"
+            @click="cancel"
           >
             <font-awesome icon="ban" class="fa-fw" />
             Cancel
diff --git a/src/views/StartView.vue b/src/views/StartView.vue
index 0bf1cdfc..31eea726 100644
--- a/src/views/StartView.vue
+++ b/src/views/StartView.vue
@@ -50,15 +50,15 @@
         <div class="grid grid-cols-1 sm:grid-cols-2 gap-2 mt-4">
           <a
             v-if="PASSKEYS_ENABLED"
-            @click="onClickNewPasskey()"
             class="block w-full text-center text-lg uppercase bg-gradient-to-b from-blue-400 to-blue-700 shadow-[inset_0_-1px_0_0_rgba(0,0,0,0.5)] text-white px-2 py-3 rounded-md mb-2 cursor-pointer"
+            @click="onClickNewPasskey()"
           >
             Generate one with a passkey
           </a>
           <a
-            @click="onClickNewSeed()"
             class="block w-full text-center text-lg uppercase bg-gradient-to-b from-blue-400 to-blue-700 shadow-[inset_0_-1px_0_0_rgba(0,0,0,0.5)] text-white px-2 py-3 rounded-md mb-2 cursor-pointer"
             data-testId="newSeed"
+            @click="onClickNewSeed()"
           >
             Generate one with a new seed
           </a>
@@ -69,15 +69,15 @@
         </p>
         <div class="grid grid-cols-1 sm:grid-cols-2 gap-2 mt-2">
           <a
-            @click="onClickNo()"
             class="block w-full text-center text-md uppercase bg-gradient-to-b from-blue-400 to-blue-700 shadow-[inset_0_-1px_0_0_rgba(0,0,0,0.5)] text-white px-1.5 py-2 rounded-md cursor-pointer"
+            @click="onClickNo()"
           >
             You have a seed
           </a>
           <a
             v-if="numAccounts > 0"
-            @click="onClickDerive()"
             class="block w-full text-center text-md uppercase bg-gradient-to-b from-blue-400 to-blue-700 shadow-[inset_0_-1px_0_0_rgba(0,0,0,0.5)] text-white px-1.5 py-2 rounded-md cursor-pointer"
+            @click="onClickDerive()"
           >
             Derive new address from existing seed
           </a>
diff --git a/src/views/TestView.vue b/src/views/TestView.vue
index fb8025cf..86906a46 100644
--- a/src/views/TestView.vue
+++ b/src/views/TestView.vue
@@ -25,8 +25,9 @@
       <h2 class="text-xl font-bold mb-4">Notiwind Alerts</h2>
 
       <button
+        class="font-bold capitalize bg-slate-900 text-white px-3 py-2 rounded-md mr-2"
         @click="
-          this.$notify(
+          $notify(
             {
               group: 'alert',
               type: 'toast',
@@ -36,14 +37,14 @@
             5000,
           )
         "
-        class="font-bold capitalize bg-slate-900 text-white px-3 py-2 rounded-md mr-2"
       >
         Toast
       </button>
 
       <button
+        class="font-bold capitalize bg-slate-600 text-white px-3 py-2 rounded-md mr-2"
         @click="
-          this.$notify(
+          $notify(
             {
               group: 'alert',
               type: 'info',
@@ -53,14 +54,14 @@
             5000,
           )
         "
-        class="font-bold capitalize bg-slate-600 text-white px-3 py-2 rounded-md mr-2"
       >
         Info
       </button>
 
       <button
+        class="font-bold capitalize bg-emerald-600 text-white px-3 py-2 rounded-md mr-2"
         @click="
-          this.$notify(
+          $notify(
             {
               group: 'alert',
               type: 'success',
@@ -70,14 +71,14 @@
             5000,
           )
         "
-        class="font-bold capitalize bg-emerald-600 text-white px-3 py-2 rounded-md mr-2"
       >
         Success
       </button>
 
       <button
+        class="font-bold capitalize bg-amber-600 text-white px-3 py-2 rounded-md mr-2"
         @click="
-          this.$notify(
+          $notify(
             {
               group: 'alert',
               type: 'warning',
@@ -87,14 +88,14 @@
             5000,
           )
         "
-        class="font-bold capitalize bg-amber-600 text-white px-3 py-2 rounded-md mr-2"
       >
         Warning
       </button>
 
       <button
+        class="font-bold capitalize bg-rose-600 text-white px-3 py-2 rounded-md mr-2"
         @click="
-          this.$notify(
+          $notify(
             {
               group: 'alert',
               type: 'danger',
@@ -104,14 +105,14 @@
             5000,
           )
         "
-        class="font-bold capitalize bg-rose-600 text-white px-3 py-2 rounded-md mr-2"
       >
         Danger
       </button>
 
       <button
+        class="font-bold capitalize bg-slate-600 text-white px-3 py-2 rounded-md mr-2"
         @click="
-          this.$notify(
+          $notify(
             {
               group: 'modal',
               type: 'notification-permission',
@@ -121,14 +122,14 @@
             -1,
           )
         "
-        class="font-bold capitalize bg-slate-600 text-white px-3 py-2 rounded-md mr-2"
       >
         Notif ON
       </button>
 
       <button
+        class="font-bold capitalize bg-slate-600 text-white px-3 py-2 rounded-md mr-2"
         @click="
-          this.$notify(
+          $notify(
             {
               group: 'modal',
               type: 'notification-mute',
@@ -138,14 +139,14 @@
             -1,
           )
         "
-        class="font-bold capitalize bg-slate-600 text-white px-3 py-2 rounded-md mr-2"
       >
         Notif MUTE
       </button>
 
       <button
+        class="font-bold capitalize bg-slate-600 text-white px-3 py-2 rounded-md mr-2"
         @click="
-          this.$notify(
+          $notify(
             {
               group: 'modal',
               type: 'notification-off',
@@ -155,7 +156,6 @@
             -1,
           )
         "
-        class="font-bold capitalize bg-slate-600 text-white px-3 py-2 rounded-md mr-2"
       >
         Notif OFF
       </button>
@@ -190,8 +190,8 @@
       <div>
         Register Passkey
         <button
-          @click="register()"
           class="font-bold capitalize bg-slate-500 text-white px-3 py-2 rounded-md mr-2"
+          @click="register()"
         >
           Simplewebauthn
         </button>
@@ -200,14 +200,14 @@
       <div>
         Create JWT
         <button
-          @click="createJwtSimplewebauthn()"
           class="font-bold capitalize bg-slate-500 text-white px-3 py-2 rounded-md mr-2"
+          @click="createJwtSimplewebauthn()"
         >
           Simplewebauthn
         </button>
         <button
-          @click="createJwtNavigator()"
           class="font-bold capitalize bg-slate-500 text-white px-3 py-2 rounded-md mr-2"
+          @click="createJwtNavigator()"
         >
           Navigator
         </button>
@@ -216,28 +216,28 @@
       <div v-if="jwt">
         Verify New JWT
         <button
-          @click="verifySimplewebauthn()"
           class="font-bold capitalize bg-slate-500 text-white px-3 py-2 rounded-md mr-2"
+          @click="verifySimplewebauthn()"
         >
           Simplewebauthn
         </button>
         <button
-          @click="verifyWebCrypto()"
           class="font-bold capitalize bg-slate-500 text-white px-3 py-2 rounded-md mr-2"
+          @click="verifyWebCrypto()"
         >
           WebCrypto
         </button>
         <button
-          @click="verifyP256()"
           class="font-bold capitalize bg-slate-500 text-white px-3 py-2 rounded-md mr-2"
+          @click="verifyP256()"
         >
           p256 - broken
         </button>
       </div>
       <div v-else>Verify New JWT -- requires creation first</div>
       <button
-        @click="verifyMyJwt()"
         class="font-bold capitalize bg-slate-500 text-white px-3 py-2 rounded-md mr-2"
+        @click="verifyMyJwt()"
       >
         Verify Hard-Coded JWT
       </button>
@@ -248,8 +248,8 @@
       See console for more output.
       <div>
         <button
-          @click="testEncryptionDecryption()"
           class="font-bold capitalize bg-slate-500 text-white px-3 py-2 rounded-md mr-2"
+          @click="testEncryptionDecryption()"
         >
           Run Test
         </button>
diff --git a/src/views/UserProfileView.vue b/src/views/UserProfileView.vue
index 66b67f94..756c02d2 100644
--- a/src/views/UserProfileView.vue
+++ b/src/views/UserProfileView.vue
@@ -9,8 +9,8 @@
       <h1 id="ViewHeading" class="text-lg text-center font-light relative px-7">
         <!-- Back -->
         <button
-          @click="$router.back()"
           class="text-lg text-center px-2 py-1 absolute -left-2 -top-1"
+          @click="$router.back()"
         >
           <font-awesome icon="chevron-left" class="fa-fw"></font-awesome>
         </button>
@@ -20,8 +20,8 @@
 
     <!-- Loading Animation -->
     <div
-      class="fixed left-6 mt-16 text-center text-4xl leading-none bg-slate-400 text-white w-14 py-2.5 rounded-full"
       v-if="isLoading"
+      class="fixed left-6 mt-16 text-center text-4xl leading-none bg-slate-400 text-white w-14 py-2.5 rounded-full"
     >
       <font-awesome icon="spinner" class="fa-spin-pulse"></font-awesome>
     </div>
diff --git a/vite.config.common.mts b/vite.config.common.mts
index 18cda0c6..1e288f5f 100644
--- a/vite.config.common.mts
+++ b/vite.config.common.mts
@@ -47,6 +47,7 @@ export async function createBuildConfig(mode: string) {
     },
     resolve: {
       alias: {
+        '@': path.resolve(__dirname, './src'),
         ...appConfig.aliasConfig,
         'nostr-tools/nip06': mode === 'development' 
           ? 'nostr-tools/nip06'
diff --git a/vite.config.ts b/vite.config.ts
new file mode 100644
index 00000000..c6bda93e
--- /dev/null
+++ b/vite.config.ts
@@ -0,0 +1,43 @@
+import { defineConfig } from "vite";
+import vue from "@vitejs/plugin-vue";
+import path from "path";
+
+export default defineConfig({
+  plugins: [vue()],
+  resolve: {
+    alias: {
+      '@': path.resolve(__dirname, './src'),
+      'nostr-tools': path.resolve(__dirname, 'node_modules/nostr-tools'),
+      'nostr-tools/nip06': path.resolve(__dirname, 'node_modules/nostr-tools/nip06'),
+      'nostr-tools/core': path.resolve(__dirname, 'node_modules/nostr-tools/core'),
+      stream: 'stream-browserify',
+      util: 'util'
+    },
+    mainFields: ['module', 'jsnext:main', 'jsnext', 'main'],
+  },
+  optimizeDeps: {
+    include: ['nostr-tools', 'nostr-tools/nip06', 'nostr-tools/core'],
+    esbuildOptions: {
+      define: {
+        global: 'globalThis'
+      }
+    }
+  },
+  build: {
+    sourcemap: true,
+    target: 'esnext',
+    commonjsOptions: {
+      include: [/node_modules/],
+      transformMixedEsModules: true
+    },
+    rollupOptions: {
+      external: ['stream', 'util'],
+      output: {
+        globals: {
+          stream: 'stream',
+          util: 'util'
+        }
+      }
+    }
+  }
+}); 
\ No newline at end of file