diff --git a/app/app.ts b/app/app.ts
index 090b170b..830e8db3 100644
--- a/app/app.ts
+++ b/app/app.ts
@@ -6,6 +6,7 @@ import { join } from 'path';
 import Problem from 'api-problem';
 import querystring from 'querystring';
 
+import { name as appName, version as appVersion } from './package.json';
 import { getLogger, httpLogger } from './src/components/log';
 import { getGitRevision, readIdpList } from './src/components/utils';
 
@@ -49,7 +50,7 @@ appRouter.get('/config', (_req: Request, res: Response, next: (err: unknown) =>
       ...config.get('frontend'),
       gitRev: state.gitRev,
       idpList: state.idpList,
-      version: process.env.npm_package_version
+      version: appVersion
     });
   } catch (err) {
     next(err);
@@ -64,9 +65,9 @@ appRouter.get('/api', (_req: Request, res: Response): void => {
     res.status(200).json({
       app: {
         gitRev: state.gitRev,
-        name: process.env.npm_package_name,
+        name: appName,
         nodeVersion: process.version,
-        version: process.env.npm_package_version
+        version: appVersion
       },
       endpoints: ['/api/v1'],
       versions: [1]
@@ -91,7 +92,7 @@ app.use((err: Problem, _req: Request, res: Response, _next: () => void): void =>
     err.send(res, null);
   } else {
     new Problem(500, 'Server Error', {
-      detail: (err.message) ? err.message : err
+      detail: err.message ? err.message : err
     }).send(res);
   }
 });
diff --git a/app/tsconfig.json b/app/tsconfig.json
index bbb05680..e5ca9a50 100644
--- a/app/tsconfig.json
+++ b/app/tsconfig.json
@@ -32,7 +32,7 @@
     // "types": [],                                      /* Specify type package names to be included without being referenced in a source file. */
     // "allowUmdGlobalAccess": true,                     /* Allow accessing UMD globals from modules. */
     // "moduleSuffixes": [],                             /* List of file name suffixes to search when resolving a module. */
-    // "resolveJsonModule": true,                        /* Enable importing .json files. */
+    "resolveJsonModule": true, /* Enable importing .json files. */
     // "noResolve": true,                                /* Disallow 'import's, 'require's or '<reference>'s from expanding the number of files TypeScript should add to a project. */
     /* JavaScript Support */
     // "allowJs": true,                                  /* Allow JavaScript files to be a part of your program. Use the 'checkJS' option to get errors from these files. */
diff --git a/frontend/package-lock.json b/frontend/package-lock.json
index 22cb29e3..283dab19 100644
--- a/frontend/package-lock.json
+++ b/frontend/package-lock.json
@@ -21,7 +21,7 @@
         "pinia-plugin-persistedstate": "^3.2.0",
         "primeflex": "^3.3.1",
         "primeicons": "^6.0.1",
-        "primevue": "~3.34.1",
+        "primevue": "^3.40.1",
         "qrcode.vue": "^3.4.1",
         "vee-validate": "^4.11.8",
         "vue": "^3.3.7",
@@ -5472,9 +5472,9 @@
       "integrity": "sha512-KDeO94CbWI4pKsPnYpA1FPjo79EsY9I+M8ywoPBSf9XMXoe/0crjbUK7jcQEDHuc0ZMRIZsxH3TYLv4TUtHmAA=="
     },
     "node_modules/primevue": {
-      "version": "3.34.1",
-      "resolved": "https://registry.npmjs.org/primevue/-/primevue-3.34.1.tgz",
-      "integrity": "sha512-5QPy8I+TMYSQgC0Bs/9vINsOVjgCOQFAr6uz49Wzcj8u04qJ2mG/z6OhAana+f4yKTTHVwHLVnuGkrIp/nI9DA==",
+      "version": "3.40.1",
+      "resolved": "https://registry.npmjs.org/primevue/-/primevue-3.40.1.tgz",
+      "integrity": "sha512-TIFjoSUDiTmlxwQddaWckzcPIpj0F8a6ZMnm0tpAD/ieyUIHnNpbAi5de8LQf8eF0b+x5EkOkdjdngSlD+iPCw==",
       "peerDependencies": {
         "vue": "^3.0.0"
       }
@@ -10983,9 +10983,9 @@
       "integrity": "sha512-KDeO94CbWI4pKsPnYpA1FPjo79EsY9I+M8ywoPBSf9XMXoe/0crjbUK7jcQEDHuc0ZMRIZsxH3TYLv4TUtHmAA=="
     },
     "primevue": {
-      "version": "3.34.1",
-      "resolved": "https://registry.npmjs.org/primevue/-/primevue-3.34.1.tgz",
-      "integrity": "sha512-5QPy8I+TMYSQgC0Bs/9vINsOVjgCOQFAr6uz49Wzcj8u04qJ2mG/z6OhAana+f4yKTTHVwHLVnuGkrIp/nI9DA==",
+      "version": "3.40.1",
+      "resolved": "https://registry.npmjs.org/primevue/-/primevue-3.40.1.tgz",
+      "integrity": "sha512-TIFjoSUDiTmlxwQddaWckzcPIpj0F8a6ZMnm0tpAD/ieyUIHnNpbAi5de8LQf8eF0b+x5EkOkdjdngSlD+iPCw==",
       "requires": {}
     },
     "property-expr": {
diff --git a/frontend/package.json b/frontend/package.json
index 41137823..f7ffd692 100644
--- a/frontend/package.json
+++ b/frontend/package.json
@@ -36,7 +36,7 @@
     "pinia-plugin-persistedstate": "^3.2.0",
     "primeflex": "^3.3.1",
     "primeicons": "^6.0.1",
-    "primevue": "~3.34.1",
+    "primevue": "^3.40.1",
     "qrcode.vue": "^3.4.1",
     "vee-validate": "^4.11.8",
     "vue": "^3.3.7",
diff --git a/frontend/src/App.vue b/frontend/src/App.vue
index 1400ec50..04abafb9 100644
--- a/frontend/src/App.vue
+++ b/frontend/src/App.vue
@@ -44,15 +44,28 @@ onErrorCaptured((e: Error) => {
 </script>
 
 <template>
-  <ConfirmDialog />
-  <ProgressLoader v-if="getIsLoading" />
-  <Toast />
-  <AppLayout>
-    <template #nav>
-      <Navbar />
-    </template>
-    <template #main>
-      <RouterView v-if="ready" />
-    </template>
-  </AppLayout>
+  <div class="container">
+    <ConfirmDialog />
+    <ProgressLoader v-if="getIsLoading" />
+    <Toast />
+
+    <AppLayout>
+      <template #nav>
+        <Navbar />
+      </template>
+      <template #main>
+        <RouterView v-if="ready" />
+      </template>
+    </AppLayout>
+  </div>
 </template>
+
+<style scoped>
+.container {
+  display: flex;
+  align-items: center;
+  justify-content: center;
+  min-height: 100vh;
+  width: 100%;
+}
+</style>
diff --git a/frontend/src/assets/base.css b/frontend/src/assets/base.css
deleted file mode 100644
index e910a752..00000000
--- a/frontend/src/assets/base.css
+++ /dev/null
@@ -1,86 +0,0 @@
-/* color palette from <https://github.com/vuejs/theme> */
-:root {
-  --vt-c-white: #ffffff;
-  --vt-c-white-soft: #f8f8f8;
-  --vt-c-white-mute: #f2f2f2;
-
-  --vt-c-black: #181818;
-  --vt-c-black-soft: #222222;
-  --vt-c-black-mute: #282828;
-
-  --vt-c-indigo: #2c3e50;
-
-  --vt-c-divider-light-1: rgba(60, 60, 60, 0.29);
-  --vt-c-divider-light-2: rgba(60, 60, 60, 0.12);
-  --vt-c-divider-dark-1: rgba(84, 84, 84, 0.65);
-  --vt-c-divider-dark-2: rgba(84, 84, 84, 0.48);
-
-  --vt-c-text-light-1: var(--vt-c-indigo);
-  --vt-c-text-light-2: rgba(60, 60, 60, 0.66);
-  --vt-c-text-dark-1: var(--vt-c-white);
-  --vt-c-text-dark-2: rgba(235, 235, 235, 0.64);
-}
-
-/* semantic color variables for this project */
-:root {
-  --color-background: var(--vt-c-white);
-  --color-background-soft: var(--vt-c-white-soft);
-  --color-background-mute: var(--vt-c-white-mute);
-
-  --color-border: var(--vt-c-divider-light-2);
-  --color-border-hover: var(--vt-c-divider-light-1);
-
-  --color-heading: var(--vt-c-text-light-1);
-  --color-text: var(--vt-c-text-light-1);
-
-  --section-gap: 160px;
-}
-
-/* @media (prefers-color-scheme: dark) {
-  :root {
-    --color-background: var(--vt-c-black);
-    --color-background-soft: var(--vt-c-black-soft);
-    --color-background-mute: var(--vt-c-black-mute);
-
-    --color-border: var(--vt-c-divider-dark-2);
-    --color-border-hover: var(--vt-c-divider-dark-1);
-
-    --color-heading: var(--vt-c-text-dark-1);
-    --color-text: var(--vt-c-text-dark-2);
-  }
-} */
-
-*,
-*::before,
-*::after {
-  box-sizing: border-box;
-  margin: 0;
-  font-weight: normal;
-}
-
-body {
-  min-height: 100vh;
-  color: var(--color-text);
-  background: var(--color-background);
-  transition:
-    color 0.5s,
-    background-color 0.5s;
-  line-height: 1.6;
-  font-family:
-    BCSans,
-    Inter,
-    -apple-system,
-    BlinkMacSystemFont,
-    'Segoe UI',
-    Roboto,
-    Oxygen,
-    Ubuntu,
-    Cantarell,
-    'Fira Sans',
-    'Droid Sans',
-    'Helvetica Neue',
-    sans-serif;
-  text-rendering: optimizeLegibility;
-  -webkit-font-smoothing: antialiased;
-  -moz-osx-font-smoothing: grayscale;
-}
diff --git a/frontend/src/assets/main.scss b/frontend/src/assets/main.scss
index 13ba55d4..3f32eeb0 100644
--- a/frontend/src/assets/main.scss
+++ b/frontend/src/assets/main.scss
@@ -1,13 +1,75 @@
-@import './base.css';
-@import './primevue.scss';
-@import './variables.scss';
+:root {
+  font-size: 16px;
+}
+
+body,
+body::before,
+body::after {
+  box-sizing: border-box;
+  margin: 0;
+}
 
-#app {
-  margin: 0 auto;
+body {
+  min-height: 100vh;
+  color: var(--text-color);
+  background: white;
+  transition:
+    color 0.5s,
+    background-color 0.5s;
+  font-family:
+    BCSans,
+    Inter,
+    -apple-system,
+    BlinkMacSystemFont,
+    "Segoe UI",
+    Roboto,
+    Oxygen,
+    Ubuntu,
+    Cantarell,
+    "Fira Sans",
+    "Droid Sans",
+    "Helvetica Neue",
+    sans-serif;
+  line-height: 1.6;
   font-weight: normal;
+  text-rendering: optimizeLegibility;
+  -webkit-font-smoothing: antialiased;
+  -moz-osx-font-smoothing: grayscale;
+}
+
+/* text */
+h1,
+h2,
+h3,
+h4,
+h5,
+h6 {
+  margin: 0;
+  padding: 0;
+  font-weight: 600;
+  // line-height: 1.2em;
+}
+
+h1 {
+  font-size: 2.074rem;
+}
+h2 {
+  font-size: 1.728rem;
+}
+h3 {
+  font-size: 1.44rem;
+}
+h4 {
+  font-size: 1.2rem;
+}
+h5 {
+  font-size: 1.1rem;
+}
+
+p {
+  margin-top: 0;
 }
 
-// ----- links and buttons:
 a,
 a:visited {
   color: $bcbox-link-text;
@@ -17,20 +79,14 @@ a:visited {
   }
 }
 
-.p-button,
-.p-inputswitch-slider {
-  &:hover {
-    opacity: 0.8;
-  }
-}
-// underline button text
-.p-button:hover {
-  text-decoration: underline;
-}
-// don't underline button icons
-.p-button .p-button-icon:before {
-  text-decoration: none;
+.wrap-block {
   display: inline-block;
+  overflow-wrap: break-word;
+  width: 100%;
+
+  td {
+    width: inherit;
+  }
 }
 
 .truncate {
@@ -47,130 +103,155 @@ a:visited {
   text-indent: 0 !important;
 }
 
-// -------- layout
-
-.content-center {
-  text-align: center !important;
-}
-
-.content-right {
-  text-align: right !important;
-}
-
-.permissions-modal {
-  width: 800px;
+.drop-shadow {
+  box-shadow: 0 6px 6px -1px rgb(145, 145, 145);
 }
 
-// details page / sidebar
-.details-grid {
-  h2 {
-    margin-bottom: 1rem;
+/* layout */
+.layout-main {
+  margin: 1rem;
+  @media screen and (min-width: 992px) {
+    margin: 1rem 5rem 1rem 5rem;
   }
-  .col-fixed {
-    width: 150px; // label column
+  @media screen and (min-width: 1600px) {
+    margin: 1rem 15% 1rem 15%;
   }
-  // make datatable look like grid
-  .p-datatable {
-    thead th {
-      padding-top: 0;
+}
+
+/* footer */
+.gov-footer {
+  background-color: #003366 !important;
+  border-top: 2px solid #fcba19;
+  a {
+    display: inline-block;
+    padding: 0.5rem 1rem;
+    color: #ffffff;
+    font-size: 1rem;
+    text-decoration: none;
+    &:hover {
+      text-decoration: underline;
     }
-    // highlight the row for the currently selected version
-    tr.selected-row {
-      background-color: $bcbox-highlight-background !important;
+    &:focus {
+      outline: none;
     }
-    td {
-      padding: 0.5rem;
+    &:visited {
+      color: #ffffff;
     }
-    th:first-child,
-    td:first-child {
-      padding-left: 0;
+  }
+
+  & > div:last-child {
+    order: 1;
+  }
+  .version {
+    color: #ffffff;
+    float: right;
+  }
+}
+
+/* buttons */
+.p-button:hover {
+  text-decoration: underline;
+  opacity: 0.8;
+}
+.p-button .p-button-icon:before {
+  text-decoration: none;
+  display: inline-block;
+}
+
+.p-button {
+  border-width: 2px;
+  &:not(.p-button-secondary, .p-button-success, .p-button-info, .p-button-warning, .p-button-help, .p-button-danger) {
+    color: $bcbox-primary;
+    &:not(.p-button-outlined, .p-button-text) {
+      background-color: $bcbox-primary;
+      border-color: $bcbox-primary;
+      color: $bcbox-outline-on-primary;
     }
   }
 }
-.details-value-column {
-  width: 40rem;
+
+.p-button-outlined {
+  border-width: 2px;
 }
-.sidebar .details-value-column {
-  width: 20rem;
+.p-confirm-dialog-reject {
+  border: 2px solid $bcbox-primary;
 }
-// eof details page / sidebar
 
-// wrap text
-.wrap-block {
-  display: inline-block;
-  overflow-wrap: break-word;
-  width: 100%;
+/* checkboxes, radios, input switches */
+.p-checkbox-checked .p-checkbox-box,
+.p-checkbox-box.p-highlight,
+.p-radiobutton-checked .p-radiobutton-box,
+.p-inputswitch-checked .p-inputswitch-slider:not(.p-disabled) {
+  background-color: $bcbox-primary;
+  border-color: $bcbox-primary;
+  &:hover {
+    opacity: 0.8;
+  }
 }
-td .wrap-block {
-  width: inherit;
+.p-tag {
+  background-color: $bcbox-primary;
+  font-size: 1rem;
+  padding: 0.25rem 0.75rem;
+  font-weight: 400;
 }
 
-// --------- Info/settings dialog modals
-.bcbox-info-dialog {
-  &.p-dialog {
-    .p-dialog-header {
-      padding-bottom: 0;
-
-      .svg-inline--fa {
-        color: $bcbox-primary;
-        font-size: 1.8rem;
-        padding-right: 0.75rem;
-        padding-top: 0.15rem;
-      }
+/* datatable */
+.p-datatable,
+.p-treetable {
+  .p-datatable-loading-overlay,
+  .p-treetable-loading-overlay {
+    background: white;
+    opacity: 0.8;
+  }
 
-      .p-dialog-title {
-        flex-grow: 1;
-        font-size: 1.8rem;
-        font-weight: bold;
-      }
-    }
+  thead > tr > th {
+    background-color: transparent !important;
+  }
 
-    .bcbox-info-dialog-subhead {
-      font-weight: normal;
-      margin-bottom: 1.5rem;
-      padding-left: 3.1rem;
-      @extend .wrap-block;
+  &.p-datatable-striped tbody > tr {
+    &:nth-child(even) {
+      background-color: $bcbox-table-stripe-background;
     }
   }
-}
-
-.drop-shadow {
-  box-shadow: 0 6px 6px -1px rgb(145, 145, 145);
-}
-
-.gov-footer {
-  background-color: #003366 !important;
-  border-top: 2px solid #fcba19;
-  flex-shrink: 0;
-  min-height: 2.5rem;
-  min-width: 100%;
-  padding-bottom: 0;
-  padding-top: 0;
 
-  a {
-    color: #ffffff;
-    font-size: 1rem;
-    text-decoration: none;
-    &:focus {
-      outline: none;
+  tbody {
+    tr {
+      &.p-highlight,
+      &.selected-row {
+        background: $bcbox-highlight-background !important;
+      }
+      &:focus {
+        outline: none !important;
+      }
     }
   }
 
-  .button > span {
-    color: #ffffff;
-    font-size: 1rem;
-    font-weight: normal;
-    text-decoration: none;
-    text-transform: none;
+  .p-column-title {
+    font-weight: bold;
   }
-}
 
-// ---------- datatables
+  .p-paginator {
+    justify-content: right;
+  }
 
-.p-datatable {
-  .p-datatable-loading-overlay {
-    background: white;
-    opacity: 0.8;
+  .header-center .p-column-header-content {
+    justify-content: center;
+  }
+  .content-center {
+    text-align: center !important;
+  }
+  .header-right .p-column-header-content {
+    justify-content: right;
+  }
+  .action-buttons {
+    text-align: right;
+    // width: 150px;
+  }
+
+  .action-buttons .p-button {
+    padding: 0;
+    margin-left: 1rem;
+    font-size: 1.25rem;
   }
 }
 
@@ -180,7 +261,99 @@ td .wrap-block {
     cursor: pointer;
   }
 }
+
 .p-input-icon-clear-right {
   position: absolute !important;
   right: 0rem;
 }
+
+/* modals */
+.bcbox-info-dialog {
+  width: 800px;
+  .p-dialog-header {
+    padding-bottom: 0;
+
+    .svg-inline--fa {
+      color: $bcbox-primary;
+      font-size: 1.8rem;
+      padding-right: 0.75rem;
+      border: 0;
+    }
+
+    .p-dialog-title {
+      flex-grow: 1;
+      @extend h2;
+    }
+  }
+
+  .bcbox-info-dialog-subhead {
+    font-weight: normal;
+    margin-bottom: 1.5rem;
+    padding-left: 3.1rem;
+    @extend .wrap-block;
+  }
+}
+
+.p-confirm-dialog {
+  max-width: 50%;
+}
+
+.p-dialog-footer {
+  display: flex;
+  flex-direction: row-reverse;
+  justify-content: left;
+}
+
+.p-tabview-header.p-disabled .p-tabview-nav-link {
+  color: gray;
+}
+.p-tabview-header:not(.p-disabled) .p-tabview-nav-link {
+  border-color: $bcbox-link-text;
+}
+
+/* side panel */
+
+.side-panel {
+  .panel-header {
+    margin-bottom: 1.5rem;
+
+    & > .svg-inline--fa {
+      color: $bcbox-primary;
+      margin-top: 0.4rem;
+      font-size: 1.7rem;
+    }
+    .p-button .svg-inline--fa {
+      margin-top: 0.5rem;
+      font-size: 1.2rem;
+    }
+  }
+  h1 {
+    font-size: 1.728rem;
+  }
+  h2 {
+    font-size: 1.44rem;
+    margin-bottom: 0.5rem;
+  }
+}
+
+/* details grid */
+
+.details-grid {
+  h2 {
+    margin-bottom: 1rem;
+  }
+  .col-fixed {
+    width: 150px; // label column
+  }
+  .details-value-column {
+    width: 40rem;
+  }
+  .sidebar .details-value-column {
+    width: 20rem;
+  }
+}
+
+/* share modal */
+a.p-tabview-header-action {
+  text-decoration: none;
+}
diff --git a/frontend/src/assets/primevue.scss b/frontend/src/assets/primevue.scss
deleted file mode 100644
index af598ab2..00000000
--- a/frontend/src/assets/primevue.scss
+++ /dev/null
@@ -1,170 +0,0 @@
-.header-center .p-column-header-content {
-  justify-content: center;
-}
-
-// For datatables
-.header-right .p-column-header-content {
-  justify-content: right;
-}
-
-// For treetables
-.header-right .p-column-title {
-  display: flex;
-  justify-content: right;
-}
-
-.p-dialog-footer {
-  display: flex;
-  flex-direction: row-reverse;
-}
-
-.p-datatable {
-  .p-datatable-thead > tr > th {
-    background-color: transparent !important;
-  }
-
-  &.p-datatable-striped .p-datatable-tbody > tr {
-    &:nth-child(even) {
-      background-color: $bcbox-table-stripe-background;
-    }
-  }
-
-  tbody {
-    tr {
-      &.p-highlight {
-        background: $bcbox-highlight-background !important;
-      }
-
-      &:focus {
-        outline: none !important;
-      }
-    }
-  }
-
-  .p-checkbox {
-    .p-checkbox-box.p-highlight {
-      background-color: $bcbox-primary;
-      border-color: $bcbox-primary !important;
-
-      &:hover {
-        background-color: darken($bcbox-primary, 20%) !important;
-      }
-    }
-  }
-
-  .p-column-title {
-    font-weight: bold;
-  }
-
-  .p-paginator {
-    justify-content: right;
-  }
-
-  .action-buttons .p-button.p-button-lg {
-    padding: 0;
-    margin-left: 1rem;
-  }
-}
-
-.p-treetable {
-  .p-treetable-thead > tr > th {
-    background-color: transparent !important;
-  }
-
-  tbody {
-    tr {
-      &.p-highlight {
-        background: $bcbox-highlight-background !important;
-      }
-
-      &:focus {
-        outline: none !important;
-      }
-    }
-  }
-
-  .p-checkbox {
-    .p-checkbox-box.p-highlight {
-      background-color: $bcbox-primary;
-      border-color: $bcbox-primary !important;
-
-      &:hover {
-        background-color: darken($bcbox-primary, 20%) !important;
-      }
-    }
-  }
-
-  .p-column-title {
-    font-weight: bold;
-  }
-
-  .p-paginator {
-    justify-content: right;
-  }
-
-  .action-buttons .p-button.p-button-lg {
-    padding: 0;
-    margin-left: 1rem;
-  }
-}
-
-// Primary color overrides for buttons and action items (checkboxes etc)
-// Note this could be eventually replaced by a custom themeing (which has JUST been introduced in Primevue)
-// once it is more settled implementation-wise
-.p-button {
-  &:not(.p-button-secondary, .p-button-success, .p-button-info, .p-button-warning, .p-button-help, .p-button-danger) {
-    color: $bcbox-primary !important;
-
-    &:not(.p-button-outlined, .p-button-text) {
-      background-color: $bcbox-primary;
-      border-color: $bcbox-primary;
-      color: $bcbox-outline-on-primary !important;
-    }
-  }
-}
-
-.p-checkbox,
-.p-radiobutton {
-  &.p-checkbox-checked,
-  &.p-radiobutton-checked {
-    .p-checkbox-box,
-    .p-radiobutton-box {
-      background-color: $bcbox-primary;
-      border-color: $bcbox-primary !important;
-
-      &:hover {
-        background-color: darken($bcbox-primary, 20%) !important;
-      }
-    }
-  }
-}
-
-.p-inputswitch.p-inputswitch-checked {
-  .p-inputswitch-slider {
-    background-color: $bcbox-primary;
-  }
-
-  &:not(.p-disabled) {
-    &:hover {
-      .p-inputswitch-slider {
-        background-color: darken($bcbox-primary, 10%) !important;
-      }
-    }
-  }
-}
-
-.p-tag {
-  background-color: $bcbox-primary;
-  font-size: 1rem;
-  padding: 0.25rem 0.75rem;
-  font-weight: normal;
-}
-
-h1,
-h2,
-h3,
-h4,
-h5 {
-  font-weight: 600;
-  line-height: 1.2em;
-}
diff --git a/frontend/src/assets/variables.scss b/frontend/src/assets/variables.scss
index de191499..a7c46cdb 100644
--- a/frontend/src/assets/variables.scss
+++ b/frontend/src/assets/variables.scss
@@ -1,9 +1,17 @@
-// General font/etc colors
+/* --------- variable overrides for primevue--------- */
+// ref: https://primevue.org/colors/
+:root {
+  --text-color: #495057;
+  --primary-color: #036;
+}
+
+/* -------- custom css variables --------- */
+// buttons, links
 $bcbox-primary: #036;
 $bcbox-link-text: #1a5a96;
 $bcbox-link-text-hover: #00f;
 $bcbox-outline-on-primary: #fff;
 
-// Panel/row/etc backgrounds
+// highlighted sections, table rows
 $bcbox-highlight-background: #d9e1e8;
 $bcbox-table-stripe-background: #f2f2f2;
diff --git a/frontend/src/components/bucket/BucketList.vue b/frontend/src/components/bucket/BucketList.vue
index 711c2039..df21cb33 100644
--- a/frontend/src/components/bucket/BucketList.vue
+++ b/frontend/src/components/bucket/BucketList.vue
@@ -46,29 +46,30 @@ onMounted(async () => {
 </script>
 
 <template>
-  <div>
-    <div>
-      <h1>Select a bucket</h1>
-      <h2>Buckets are containers for storing objects.</h2>
-      <Message
-        v-if="getConfig?.notificationBanner"
-        severity="warn"
-      >
-        {{ getConfig?.notificationBanner }}
-      </Message>
+  <Message
+    v-if="getConfig?.notificationBanner"
+    severity="warn"
+  >
+    {{ getConfig?.notificationBanner }}
+  </Message>
+
+  <div class="flex flex-wrap">
+    <div class="flex-grow-1">
+      <h1 class="">Select a bucket</h1>
+      <h4 class="mb-4">Buckets are containers for storing objects.</h4>
     </div>
-    <div class="flex justify-content-end">
+
+    <div class="flex-none align-items-right">
       <Button
         v-if="usePermissionStore().isUserElevatedRights()"
-        label="Primary"
-        class="p-button-outlined mt-4"
+        label="Connect bucket to BCBox"
+        class="p-button-outlined my-4"
         data-test="connect-bucket"
         aria-label="Configure bucket"
+        icon="pi pi-plus"
         @click="showBucketConfig()"
-      >
-        <font-awesome-icon icon="fa-solid fa-plus" />
-        Connect bucket to BCBox
-      </Button>
+      />
+
       <!-- Bucket config dialog -->
       <Dialog
         class="bcbox-info-dialog"
@@ -113,29 +114,22 @@ onMounted(async () => {
         />
       </Dialog>
     </div>
-    <div class="flex">
-      <div class="flex-grow-1">
-        <BucketTable
-          @show-sidebar-info="showSidebarInfo"
-          @show-bucket-config="showBucketConfig"
-        />
-      </div>
-      <div
-        v-if="sidebarInfo"
-        class="flex-shrink-0 ml-3"
-        style="max-width: 33%; min-width: 33%"
-      >
-        <BucketSidebar
-          :sidebar-info="sidebarInfo"
-          @close-sidebar-info="closeSidebarInfo"
-        />
-      </div>
+  </div>
+  <div class="flex">
+    <div class="flex-grow-1">
+      <BucketTable
+        @show-sidebar-info="showSidebarInfo"
+        @show-bucket-config="showBucketConfig"
+      />
+    </div>
+    <div
+      v-if="sidebarInfo"
+      class="flex-shrink-0 w-4 pl-4 max-w-28rem"
+    >
+      <BucketSidebar
+        :sidebar-info="sidebarInfo"
+        @close-sidebar-info="closeSidebarInfo"
+      />
     </div>
   </div>
 </template>
-
-<style lang="scss" scoped>
-button {
-  text-indent: 10px;
-}
-</style>
diff --git a/frontend/src/components/bucket/BucketSidebar.vue b/frontend/src/components/bucket/BucketSidebar.vue
index 513b34fd..1b3011b5 100644
--- a/frontend/src/components/bucket/BucketSidebar.vue
+++ b/frontend/src/components/bucket/BucketSidebar.vue
@@ -65,32 +65,25 @@ watch(props, () => {
 </script>
 
 <template>
-  <div class="flex justify-content-start">
-    <div class="flex col align-items-center pl-0">
-      <font-awesome-icon
-        icon="fa-solid fa-circle-info"
-        style="font-size: 2rem"
-      />
-      <h1>Bucket details</h1>
-    </div>
-    <div class="col-fixed align-items-center">
+  <div class="side-panel pl-4">
+    <div class="flex panel-header align-items-start">
+      <font-awesome-icon icon="fa-solid fa-circle-info" />
+      <h1 class="mt-0 ml-3 flex-grow-1">Bucket details</h1>
       <Button
-        class="p-button-lg p-button-rounded p-button-text black"
+        class="p-button-text pt-0"
         @click="closeSidebarInfo"
       >
-        <font-awesome-icon icon="fa-solid fa-xmark" />
+        <font-awesome-icon icon="fa-xmark" />
       </Button>
     </div>
-  </div>
 
-  <div class="pl-2 sidebar">
     <div class="grid details-grid grid-nogutter">
       <div class="col-12">
         <h2>Properties</h2>
       </div>
       <div class="grid overflow-hidden">
         <div class="col-fixed">Bucket Name:</div>
-        <div class="col wrap-block w-6">
+        <div class="col wrap-block">
           {{ props.sidebarInfo?.bucketName }}
         </div>
       </div>
@@ -114,17 +107,3 @@ watch(props, () => {
     </div>
   </div>
 </template>
-
-<style lang="scss" scoped>
-h1 {
-  padding-left: 1rem;
-}
-
-h2 {
-  font-weight: bold;
-}
-
-.black {
-  color: black;
-}
-</style>
diff --git a/frontend/src/components/bucket/BucketTable.vue b/frontend/src/components/bucket/BucketTable.vue
index 42be96f2..e42d110e 100644
--- a/frontend/src/components/bucket/BucketTable.vue
+++ b/frontend/src/components/bucket/BucketTable.vue
@@ -242,138 +242,136 @@ watch(getBuckets, () => {
 </script>
 
 <template>
-  <div>
-    <TreeTable
-      :loading="getIsLoading"
-      :value="treeData"
-      :expanded-keys="expandedKeys"
-      data-key="bucketId"
-      class="p-treetable-sm"
-      responsive-layout="scroll"
-      :paginator="true"
-      :rows="10"
-      paginator-template="RowsPerPageDropdown CurrentPageReport PrevPageLink NextPageLink "
-      current-page-report-template="{first}-{last} of {totalRecords}"
-      :rows-per-page-options="[10, 20, 50]"
-      sort-field="bucketName"
-      :sort-order="1"
+  <TreeTable
+    :loading="getIsLoading"
+    :value="treeData"
+    :expanded-keys="expandedKeys"
+    data-key="bucketId"
+    class="p-treetable-sm"
+    responsive-layout="scroll"
+    :paginator="true"
+    :rows="10"
+    paginator-template="RowsPerPageDropdown CurrentPageReport PrevPageLink NextPageLink "
+    current-page-report-template="{first}-{last} of {totalRecords}"
+    :rows-per-page-options="[10, 20, 50]"
+    sort-field="bucketName"
+    :sort-order="1"
+  >
+    <template #empty>
+      <div
+        v-if="!getIsLoading"
+        class="flex justify-content-center"
+      >
+        <h3>There are no buckets associated with your account.</h3>
+      </div>
+    </template>
+    <template #loadingicon>
+      <Spinner />
+    </template>
+    <Column
+      field="bucketName"
+      header="Bucket Name"
+      header-style="padding-left: 50px"
+      body-class="truncate"
+      expander
     >
-      <template #empty>
-        <div
-          v-if="!getIsLoading"
-          class="flex justify-content-center"
+      <template #body="{ node }">
+        <span class="row-head mr-2">
+          <font-awesome-icon
+            v-if="!node.data.dummy"
+            icon="fa-solid fa-box-open"
+          />
+          <font-awesome-icon
+            v-else
+            icon="fa-solid fa-folder"
+          />
+        </span>
+        <span
+          v-if="node.data.bucketName.length > 150"
+          v-tooltip.bottom="{ value: node.data.bucketName }"
         >
-          <h3>There are no buckets associated with your account.</h3>
-        </div>
-      </template>
-      <template #loadingicon>
-        <Spinner />
+          <BucketTableBucketName :node="node" />
+        </span>
+        <span v-else>
+          <BucketTableBucketName :node="node" />
+        </span>
       </template>
-      <Column
-        field="bucketName"
-        header="Bucket Name"
-        header-style="padding-left: 50px"
-        body-class="truncate"
-        expander
-      >
-        <template #body="{ node }">
-          <span class="row-head mr-2">
-            <font-awesome-icon
-              v-if="!node.data.dummy"
-              icon="fa-solid fa-box-open"
-            />
-            <font-awesome-icon
-              v-else
-              icon="fa-solid fa-folder"
-            />
-          </span>
-          <span
-            v-if="node.data.bucketName.length > 150"
-            v-tooltip.bottom="{ value: node.data.bucketName }"
-          >
-            <BucketTableBucketName :node="node" />
-          </span>
-          <span v-else>
-            <BucketTableBucketName :node="node" />
-          </span>
-        </template>
-      </Column>
-      <Column
-        header="Actions"
-        header-style="width: 250px"
-        header-class="header-right"
-        body-class="content-right action-buttons"
-      >
-        <template #body="{ node }">
-          <span v-if="!node.data.dummy">
-            <Button
-              v-if="permissionStore.isBucketActionAllowed(node.data.bucketId, getUserId, Permissions.UPDATE)"
-              v-tooltip.bottom="'Configure bucket'"
-              class="p-button-lg p-button-text"
-              aria-label="Configure bucket"
-              @click="showBucketConfig(node.data)"
-            >
-              <font-awesome-icon icon="fas fa-cog" />
-            </Button>
-            <Button
-              v-if="permissionStore.isBucketActionAllowed(node.data.bucketId, getUserId, Permissions.MANAGE)"
-              v-tooltip.bottom="'Bucket permissions'"
-              class="p-button-lg p-button-text"
-              aria-label="Bucket permissions"
-              @click="showPermissions(node.data.bucketId, node.data.bucketName)"
-            >
-              <font-awesome-icon icon="fa-solid fa-users" />
-            </Button>
-            <SyncButton
-              label-text="Synchronize bucket"
-              :bucket-id="node.data.bucketId"
-            />
-            <Button
-              v-if="permissionStore.isBucketActionAllowed(node.data.bucketId, getUserId, Permissions.READ)"
-              v-tooltip.bottom="'Bucket details'"
-              class="p-button-lg p-button-rounded p-button-text"
-              aria-label="Bucket details"
-              @click="showSidebarInfo(node.data.bucketId)"
-            >
-              <font-awesome-icon icon="fa-solid fa-circle-info" />
-            </Button>
-            <Button
-              v-if="permissionStore.isBucketActionAllowed(node.data.bucketId, getUserId, Permissions.DELETE)"
-              v-tooltip.bottom="'Delete bucket'"
-              class="p-button-lg p-button-text p-button-danger"
-              aria-label="Delete bucket"
-              @click="confirmDeleteBucket(node.data.bucketId)"
-            >
-              <font-awesome-icon icon="fa-solid fa-trash" />
-            </Button>
-          </span>
-        </template>
-      </Column>
-    </TreeTable>
-
-    <!-- eslint-disable vue/no-v-model-argument -->
-    <Dialog
-      v-model:visible="permissionsVisible"
-      :draggable="false"
-      :modal="true"
-      class="bcbox-info-dialog permissions-modal"
+    </Column>
+    <Column
+      header="Actions"
+      header-class="text-right"
+      body-class="action-buttons"
+      style="width: 250px"
     >
-      <!-- eslint-enable vue/no-v-model-argument -->
-      <template #header>
-        <font-awesome-icon
-          icon="fas fa-users"
-          fixed-width
-        />
-        <span class="p-dialog-title">Bucket Permissions</span>
+      <template #body="{ node }">
+        <span v-if="!node.data.dummy">
+          <Button
+            v-if="permissionStore.isBucketActionAllowed(node.data.bucketId, getUserId, Permissions.UPDATE)"
+            v-tooltip.bottom="'Configure bucket'"
+            class="p-button-lg p-button-text"
+            aria-label="Configure bucket"
+            @click="showBucketConfig(node.data)"
+          >
+            <font-awesome-icon icon="fas fa-cog" />
+          </Button>
+          <Button
+            v-if="permissionStore.isBucketActionAllowed(node.data.bucketId, getUserId, Permissions.MANAGE)"
+            v-tooltip.bottom="'Bucket permissions'"
+            class="p-button-lg p-button-text"
+            aria-label="Bucket permissions"
+            @click="showPermissions(node.data.bucketId, node.data.bucketName)"
+          >
+            <font-awesome-icon icon="fa-solid fa-users" />
+          </Button>
+          <SyncButton
+            label-text="Synchronize bucket"
+            :bucket-id="node.data.bucketId"
+          />
+          <Button
+            v-if="permissionStore.isBucketActionAllowed(node.data.bucketId, getUserId, Permissions.READ)"
+            v-tooltip.bottom="'Bucket details'"
+            class="p-button-lg p-button-rounded p-button-text"
+            aria-label="Bucket details"
+            @click="showSidebarInfo(node.data.bucketId)"
+          >
+            <font-awesome-icon icon="fa-solid fa-circle-info" />
+          </Button>
+          <Button
+            v-if="permissionStore.isBucketActionAllowed(node.data.bucketId, getUserId, Permissions.DELETE)"
+            v-tooltip.bottom="'Delete bucket'"
+            class="p-button-lg p-button-text p-button-danger"
+            aria-label="Delete bucket"
+            @click="confirmDeleteBucket(node.data.bucketId)"
+          >
+            <font-awesome-icon icon="fa-solid fa-trash" />
+          </Button>
+        </span>
       </template>
-
-      <h3 class="bcbox-info-dialog-subhead">
-        {{ permissionBucketName }}
-      </h3>
-
-      <BucketPermission :bucket-id="permissionsBucketId" />
-    </Dialog>
-  </div>
+    </Column>
+  </TreeTable>
+
+  <!-- eslint-disable vue/no-v-model-argument -->
+  <Dialog
+    v-model:visible="permissionsVisible"
+    :draggable="false"
+    :modal="true"
+    class="bcbox-info-dialog"
+  >
+    <!-- eslint-enable vue/no-v-model-argument -->
+    <template #header>
+      <font-awesome-icon
+        icon="fas fa-users"
+        fixed-width
+      />
+      <span class="p-dialog-title">Bucket Permissions</span>
+    </template>
+
+    <h3 class="bcbox-info-dialog-subhead">
+      {{ permissionBucketName }}
+    </h3>
+
+    <BucketPermission :bucket-id="permissionsBucketId" />
+  </Dialog>
 </template>
 
 <style scoped lang="scss">
diff --git a/frontend/src/components/layout/AppLayout.vue b/frontend/src/components/layout/AppLayout.vue
index 0b8f2e7c..d1af21ed 100644
--- a/frontend/src/components/layout/AppLayout.vue
+++ b/frontend/src/components/layout/AppLayout.vue
@@ -3,7 +3,7 @@ import { Header, Footer } from '@/components/layout';
 </script>
 
 <template>
-  <div class="layout-app">
+  <div class="w-full min-h-screen flex flex-column">
     <!-- Header/Nav -->
     <div class="layout-head">
       <Header />
@@ -11,37 +11,13 @@ import { Header, Footer } from '@/components/layout';
     </div>
 
     <!-- Main views -->
-    <main class="layout-container">
+    <main class="layout-main pt-3 flex-auto">
       <slot name="main" />
     </main>
 
     <!-- Footer -->
-    <footer class="layout-footer">
+    <footer class="flex-shrink-0">
       <Footer />
     </footer>
   </div>
 </template>
-
-<style scoped lang="scss">
-.layout-app {
-  display: flex;
-  flex-direction: column;
-  align-items: flex-start;
-  min-height: 100vh;
-  width: 100%;
-  .layout-head {
-    flex: 0;
-    width: 100%;
-  }
-  .layout-container {
-    flex: 1;
-    padding-top: 20px;
-    padding-left: 100px;
-    padding-right: 100px;
-    width: 100%;
-  }
-  .layout-footer {
-    width: 100%;
-  }
-}
-</style>
diff --git a/frontend/src/components/layout/Footer.vue b/frontend/src/components/layout/Footer.vue
index a2c1972c..0f166636 100644
--- a/frontend/src/components/layout/Footer.vue
+++ b/frontend/src/components/layout/Footer.vue
@@ -1,7 +1,6 @@
 <script setup lang="ts">
 import { storeToRefs } from 'pinia';
 
-import { Button } from '@/lib/primevue';
 import { useConfigStore } from '@/store';
 
 // Store
@@ -11,68 +10,54 @@ const { getConfig } = storeToRefs(useConfigStore());
 <template>
   <div class="gov-footer flex justify-content-between">
     <div>
-      <Button id="footer-home">
-        <a
-          href="https://www.gov.bc.ca/"
-          target="_blank"
-        >
-          Home
-        </a>
-      </Button>
-      <Button id="footer-about">
-        <a
-          href="https://www2.gov.bc.ca/gov/content/about-gov-bc-ca"
-          target="_blank"
-        >
-          About gov.bc.ca
-        </a>
-      </Button>
-      <Button id="footer-disclaimer">
-        <a
-          href="http://gov.bc.ca/disclaimer"
-          target="_blank"
-        >
-          Disclaimer
-        </a>
-      </Button>
-      <Button id="footer-privacy">
-        <a
-          href="http://gov.bc.ca/privacy"
-          target="_blank"
-        >
-          Privacy
-        </a>
-      </Button>
-      <Button id="footer-accessibility">
-        <a
-          href="http://gov.bc.ca/webaccessibility"
-          target="_blank"
-        >
-          Accessibility
-        </a>
-      </Button>
-      <Button id="footer-copyright">
-        <a
-          href="http://gov.bc.ca/copyright"
-          target="_blank"
-        >
-          Copyright
-        </a>
-      </Button>
-      <Button id="footer-contact">
-        <a
-          href="https://www2.gov.bc.ca/gov/content/home/contact-us"
-          target="_blank"
-        >
-          Contact Us
-        </a>
-      </Button>
+      <a
+        href="https://www.gov.bc.ca/"
+        target="_blank"
+      >
+        Home
+      </a>
+      <a
+        href="https://www2.gov.bc.ca/gov/content/about-gov-bc-ca"
+        target="_blank"
+      >
+        About gov.bc.ca
+      </a>
+      <a
+        href="http://gov.bc.ca/disclaimer"
+        target="_blank"
+      >
+        Disclaimer
+      </a>
+      <a
+        href="http://gov.bc.ca/privacy"
+        target="_blank"
+      >
+        Privacy
+      </a>
+      <a
+        href="http://gov.bc.ca/webaccessibility"
+        target="_blank"
+      >
+        Accessibility
+      </a>
+      <a
+        href="http://gov.bc.ca/copyright"
+        target="_blank"
+      >
+        Copyright
+      </a>
+      <a
+        href="https://www2.gov.bc.ca/gov/content/home/contact-us"
+        target="_blank"
+      >
+        Contact Us
+      </a>
     </div>
     <div
       v-if="getConfig"
-      class="flex align-items-center justify-content-center text-white mr-3"
+      class="version px-3 py-2"
     >
-      v{{ getConfig.version }}-{{ getConfig.gitRev.substring(0, 8) }}
+      v{{ getConfig.version }}{{ getConfig.gitRev ? '-' + getConfig.gitRev.substring(0, 8) : '' }}
     </div>
   </div>
 </template>
diff --git a/frontend/src/components/layout/Header.vue b/frontend/src/components/layout/Header.vue
index 1c4a26c6..bdcd3d11 100644
--- a/frontend/src/components/layout/Header.vue
+++ b/frontend/src/components/layout/Header.vue
@@ -5,9 +5,12 @@ import { LoginButton } from '@/components/layout';
 <template>
   <header>
     <nav id="header-branding">
-      <div class="grid align-items-center justify-content-center">
-        <div class="col-fixed">
-          <a href="https://www2.gov.bc.ca">
+      <div class="flex flex-row flex-wrap align-items-center py-3 lg:px-7">
+        <div class="flex flex-none">
+          <a
+            href="https://www2.gov.bc.ca"
+            class="pl-1"
+          >
             <img
               src="@/assets/images/bc_logo.svg"
               width="181"
@@ -16,15 +19,10 @@ import { LoginButton } from '@/components/layout';
             />
           </a>
         </div>
-        <div class="col">
-          <div
-            id="title-branding"
-            class="justify-content-left"
-          >
-            <span>BCBox</span>
-          </div>
+        <div class="flex flex-grow-1 ml-2">
+          <h2 class="m-0">BCBox</h2>
         </div>
-        <div class="col-fixed">
+        <div class="flex flex-none mx-3">
           <LoginButton />
         </div>
       </div>
@@ -35,24 +33,14 @@ import { LoginButton } from '@/components/layout';
 <style lang="scss" scoped>
 #header-branding {
   background-color: #003366;
-  font-size: 13px;
   color: white;
-  padding: 0.5rem 3rem 0rem 3rem;
   white-space: nowrap;
   box-shadow: 0 6px 8px -4px #b3b1b3;
   -webkit-box-shadow: 0 6px 8px -4px #b3b1b3;
   -moz-box-shadow: 0 6px 8px -4px #b3b1b3;
+
   @media not print {
     border-bottom: 2px solid #fcba19;
   }
 }
-
-#title-branding {
-  padding-left: 10px;
-  font-size: 20px;
-  > span {
-    font-weight: 600;
-    font-size: 1.5em;
-  }
-}
 </style>
diff --git a/frontend/src/components/layout/Navbar.vue b/frontend/src/components/layout/Navbar.vue
index 4bb4289e..58f19c55 100644
--- a/frontend/src/components/layout/Navbar.vue
+++ b/frontend/src/components/layout/Navbar.vue
@@ -10,7 +10,7 @@ const { getIsAuthenticated } = storeToRefs(useAuthStore());
 </script>
 
 <template>
-  <nav class="navigation-main">
+  <nav class="navigation-main lg:px-7">
     <Toolbar>
       <template #start>
         <ol class="list-none m-0 p-0 flex flex-row align-items-center font-semibold">
@@ -58,7 +58,6 @@ const { getIsAuthenticated } = storeToRefs(useAuthStore());
   background-color: #38598a;
   color: #fcba19;
   display: flex;
-  padding: 0rem 3rem 0rem 3rem;
   width: 100%;
   box-shadow: 0 6px 8px -4px #b3b1b3;
   -webkit-box-shadow: 0 6px 8px -4px #b3b1b3;
diff --git a/frontend/src/components/layout/ProgressLoader.vue b/frontend/src/components/layout/ProgressLoader.vue
index 6fb748a7..179b0b36 100644
--- a/frontend/src/components/layout/ProgressLoader.vue
+++ b/frontend/src/components/layout/ProgressLoader.vue
@@ -22,6 +22,7 @@ const { getLoadingMode, getLoadingValue } = storeToRefs(appStore);
 <style lang="scss" scoped>
 .app-loader {
   position: fixed;
+  top: 0;
   width: 100%;
   z-index: 999;
 
diff --git a/frontend/src/components/object/DownloadObjectButton.vue b/frontend/src/components/object/DownloadObjectButton.vue
index 98e6cca0..1c0d6e89 100644
--- a/frontend/src/components/object/DownloadObjectButton.vue
+++ b/frontend/src/components/object/DownloadObjectButton.vue
@@ -65,6 +65,7 @@ const download = () => {
   </Button>
   <Button
     v-else
+    v-tooltip.bottom="'Download object'"
     class="mr-2"
     outlined
     :disabled="props.disabled"
diff --git a/frontend/src/components/object/ObjectFileDetails.vue b/frontend/src/components/object/ObjectFileDetails.vue
index 8787e50b..ececa986 100644
--- a/frontend/src/components/object/ObjectFileDetails.vue
+++ b/frontend/src/components/object/ObjectFileDetails.vue
@@ -138,17 +138,17 @@ watch([props, getObjects], async () => {
 
 <template>
   <div v-if="obj">
-    <div class="grid pol-0">
+    <div class="grid grid-nogutter">
       <div class="col-12">
-        <h1 class="pl-1 heading">File details</h1>
+        <h1 class="heading">File details</h1>
       </div>
       <div class="flex col justify-content-start">
         <div class="flex col align-items-center heading">
           <font-awesome-icon
             icon="fa-solid fa-circle-info"
-            style="font-size: 2rem"
+            class="text-3xl pr-3"
           />
-          <h2 class="pl-1">
+          <h2 class="">
             {{ obj.name }}
           </h2>
         </div>
@@ -200,7 +200,7 @@ watch([props, getObjects], async () => {
         />
       </div>
       <Divider layout="vertical" />
-      <div class="flex flex-column w-6 gap-3 py-5">
+      <div class="flex flex-column w-6 gap-4 xl:pl-3 py-5">
         <div class="flex flex-row-reverse">
           <ObjectUploadBasic
             v-if="permissionStore.isObjectActionAllowed(props.objectId, getUserId, Permissions.UPDATE, bucketId)"
@@ -229,7 +229,7 @@ watch([props, getObjects], async () => {
     v-model:visible="permissionsVisible"
     :draggable="false"
     :modal="true"
-    class="bcbox-info-dialog permissions-modal"
+    class="bcbox-info-dialog"
   >
     <!-- eslint-enable vue/no-v-model-argument -->
     <template #header>
diff --git a/frontend/src/components/object/ObjectList.vue b/frontend/src/components/object/ObjectList.vue
index dcddd191..f845dce3 100644
--- a/frontend/src/components/object/ObjectList.vue
+++ b/frontend/src/components/object/ObjectList.vue
@@ -91,6 +91,7 @@ onMounted(async () => {
     <div>
       <Button
         v-if="permissionStore.isBucketActionAllowed(props.bucketId as string, getUserId, Permissions.CREATE)"
+        v-tooltip.bottom="'Upload object'"
         class="mr-2"
         :disabled="displayUpload"
         aria-label="Show object"
@@ -127,8 +128,7 @@ onMounted(async () => {
       </div>
       <div
         v-if="objectInfoId"
-        class="flex-shrink-0 ml-3"
-        style="max-width: 33%; min-width: 33%"
+        class="flex-shrink-1 w-4"
       >
         <ObjectSidebar
           :object-id="objectInfoId"
diff --git a/frontend/src/components/object/ObjectMetadata.vue b/frontend/src/components/object/ObjectMetadata.vue
index 1d28d8a5..3ff773b6 100644
--- a/frontend/src/components/object/ObjectMetadata.vue
+++ b/frontend/src/components/object/ObjectMetadata.vue
@@ -128,7 +128,7 @@ watch([props, tsGetMetadata, vsGetMetadata], () => {
     v-model:visible="editing"
     :draggable="false"
     :modal="true"
-    class="bcbox-info-dialog permissions-modal"
+    class="bcbox-info-dialog"
   >
     <!-- eslint-enable vue/no-v-model-argument -->
     <template #header>
diff --git a/frontend/src/components/object/ObjectMetadataTagForm.vue b/frontend/src/components/object/ObjectMetadataTagForm.vue
index b1d55b22..c4bf53fd 100644
--- a/frontend/src/components/object/ObjectMetadataTagForm.vue
+++ b/frontend/src/components/object/ObjectMetadataTagForm.vue
@@ -190,13 +190,13 @@ onBeforeMount(() => {
       </span>
 
       <Button
-        class="mt-5"
+        class="mt-5 mr-2"
         label="Save"
         type="submit"
         icon="pi pi-check"
       />
       <Button
-        class="p-button-text mt-2"
+        class="p-button-outlined mt-2"
         label="Cancel"
         icon="pi pi-times"
         @click="onCancel"
diff --git a/frontend/src/components/object/ObjectSidebar.vue b/frontend/src/components/object/ObjectSidebar.vue
index 3ede4bcf..d8105b06 100644
--- a/frontend/src/components/object/ObjectSidebar.vue
+++ b/frontend/src/components/object/ObjectSidebar.vue
@@ -46,25 +46,18 @@ watch(
 </script>
 
 <template>
-  <div class="flex justify-content-start">
-    <div class="flex col align-items-center heading">
-      <font-awesome-icon
-        icon="fa-solid fa-circle-info"
-        style="font-size: 2rem"
-      />
-      <h1>File details</h1>
-    </div>
-    <div>
+  <div class="side-panel pl-4 pt-2">
+    <div class="flex panel-header align-items-start">
+      <font-awesome-icon icon="fa-solid fa-circle-info" />
+      <h1 class="mt-0 flex-grow-1">File details</h1>
       <Button
-        class="black"
-        icon="pi pi-times"
-        text
-        rounded
+        class="p-button-rounded p-button-text pt-0 mt-0"
         @click="closeObjectInfo"
-      />
+      >
+        <font-awesome-icon icon="fa-xmark" />
+      </Button>
     </div>
-  </div>
-  <div class="pl-2 sidebar">
+
     <ObjectProperties
       :object-id="props.objectId"
       :full-view="false"
diff --git a/frontend/src/components/object/ObjectTable.vue b/frontend/src/components/object/ObjectTable.vue
index 4ea3dec7..cab09394 100644
--- a/frontend/src/components/object/ObjectTable.vue
+++ b/frontend/src/components/object/ObjectTable.vue
@@ -101,7 +101,7 @@ const filters = ref({
 </script>
 
 <template>
-  <div>
+  <div class="object-table">
     <DataTable
       v-model:selection="objectStore.selectedObjects"
       v-model:filters="filters"
@@ -171,7 +171,7 @@ const filters = ref({
         field="name"
         :sortable="true"
         header="Name"
-        header-style="width: 25%"
+        header-style="min-width: 25%"
         body-class="truncate"
       >
         <template #body="{ data }">
@@ -184,6 +184,7 @@ const filters = ref({
         field="id"
         :sortable="true"
         header="Object ID"
+        style="width: 150px"
       >
         <template #body="{ data }">
           <div v-tooltip.bottom="{ value: data.id }">
@@ -194,6 +195,7 @@ const filters = ref({
       <Column
         field="lastUpdatedDate"
         header="Updated date"
+        style="width: 300px"
         :sortable="true"
         :hidden="props.objectInfoId ? true : false"
       >
@@ -204,6 +206,7 @@ const filters = ref({
       <Column
         field="publicSharing"
         header="Public"
+        style="width: 100px"
       >
         <template #body="{ data }">
           <ObjectPublicToggle
@@ -217,9 +220,9 @@ const filters = ref({
       </Column>
       <Column
         header="Actions"
-        header-style="width: 250px"
+        header-style="min-width: 270px"
         header-class="header-right"
-        body-class="content-right action-buttons"
+        body-class="action-buttons"
       >
         <template #body="{ data }">
           <ShareObjectButton :id="data.id" />
@@ -275,7 +278,7 @@ const filters = ref({
       v-model:visible="permissionsVisible"
       :draggable="false"
       :modal="true"
-      class="bcbox-info-dialog permissions-modal"
+      class="bcbox-info-dialog"
     >
       <!-- eslint-enable vue/no-v-model-argument -->
       <template #header>
diff --git a/frontend/src/components/object/ObjectTag.vue b/frontend/src/components/object/ObjectTag.vue
index 7ec024d4..c9843a0e 100644
--- a/frontend/src/components/object/ObjectTag.vue
+++ b/frontend/src/components/object/ObjectTag.vue
@@ -129,7 +129,7 @@ watch([props, tsGetTagging, vsGetTagging], () => {
     v-model:visible="editing"
     :draggable="false"
     :modal="true"
-    class="bcbox-info-dialog permissions-modal"
+    class="bcbox-info-dialog"
   >
     <!-- eslint-enable vue/no-v-model-argument -->
     <template #header>
diff --git a/frontend/src/components/object/ObjectUploadBasic.vue b/frontend/src/components/object/ObjectUploadBasic.vue
index dd87dfa0..feb8d91a 100644
--- a/frontend/src/components/object/ObjectUploadBasic.vue
+++ b/frontend/src/components/object/ObjectUploadBasic.vue
@@ -42,10 +42,9 @@ const confirm = useConfirm();
 const toast = useToast();
 
 const confirmUpdate = () => {
-  let confirmMessage =  'Please confirm that you want to upload a new version.';
+  let confirmMessage = 'Please confirm that you want to upload a new version.';
   if (versionStore.findS3VersionByObjectId(props.objectId) === null) {
-    confirmMessage = 'This is a non-versioned bucket. ' +
-      'Uploading a new version will overwrite the current version.';
+    confirmMessage = 'This is a non-versioned bucket. ' + 'Uploading a new version will overwrite the current version.';
   }
   confirm.require({
     message: confirmMessage,
@@ -139,7 +138,7 @@ const closeModal = () => {
     v-model:visible="editing"
     :draggable="false"
     :modal="true"
-    class="bcbox-info-dialog permissions-modal"
+    class="bcbox-info-dialog"
   >
     <!-- eslint-enable vue/no-v-model-argument -->
     <template #header>
diff --git a/frontend/src/components/object/ObjectUploadFile.vue b/frontend/src/components/object/ObjectUploadFile.vue
index bc4ea57a..d7a6d7b8 100644
--- a/frontend/src/components/object/ObjectUploadFile.vue
+++ b/frontend/src/components/object/ObjectUploadFile.vue
@@ -108,7 +108,7 @@ const closeModal = () => {
       v-model:visible="editing"
       :draggable="false"
       :modal="true"
-      class="bcbox-info-dialog permissions-modal"
+      class="bcbox-info-dialog"
     >
       <!-- eslint-enable vue/no-v-model-argument -->
       <template #header>
diff --git a/frontend/src/components/object/ObjectVersion.vue b/frontend/src/components/object/ObjectVersion.vue
index 21fdd6d8..7ce2a9bc 100644
--- a/frontend/src/components/object/ObjectVersion.vue
+++ b/frontend/src/components/object/ObjectVersion.vue
@@ -91,7 +91,7 @@ watch(getVersions, async () => {
 </script>
 
 <template>
-  <div class="grid details-grid grid-nogutter mb-2">
+  <div class="grid grid-nogutter mb-2">
     <div class="col-12">
       <h2>Versions</h2>
     </div>
@@ -120,8 +120,8 @@ watch(getVersions, async () => {
         <Column
           field="versionNumber"
           header="Version"
-          header-style="width: 3em"
-          body-class="content-center"
+          header-style="width: 5em"
+          body-style="text-align: center"
         >
           <template #body="{ data }">
             {{ data.versionNumber }}
@@ -130,7 +130,6 @@ watch(getVersions, async () => {
         <Column
           field="updatedAt"
           header="Creation date"
-          header-style="width: 33%"
         >
           <template #body="{ data }">
             <div>
@@ -143,7 +142,6 @@ watch(getVersions, async () => {
         <Column
           field="createdBy"
           header="Created by"
-          header-style="width: 33%"
         >
           <template #body="{ data }">
             <div>
@@ -153,10 +151,13 @@ watch(getVersions, async () => {
         </Column>
         <Column
           header="Actions"
-          header-style="width: 34%"
           header-class="header-right"
-          body-class="content-right action-buttons"
+          body-class="action-buttons"
         >
+          <!--           header-class="header-right flex justify-content-end"
+          body-class="content-right action-buttons justify-content-end"
+          header-style="width: 8em"
+-->
           <template #body="{ data }">
             <DownloadObjectButton
               v-if="
@@ -183,8 +184,12 @@ watch(getVersions, async () => {
                 )
               "
               :to="{ name: RouteNames.DETAIL_OBJECTS, query: { objectId: props.objectId, versionId: data.id } }"
+              class="action-link"
             >
-              <Button class="p-button-lg p-button-rounded p-button-text">
+              <Button
+                v-tooltip.bottom="'Version details'"
+                class="p-button-lg p-button-rounded p-button-text"
+              >
                 <font-awesome-icon icon="fa-solid fa-circle-info" />
               </Button>
             </router-link>
diff --git a/frontend/src/components/object/share/ShareLinkContent.vue b/frontend/src/components/object/share/ShareLinkContent.vue
index 229ff2fe..9c5b4ace 100644
--- a/frontend/src/components/object/share/ShareLinkContent.vue
+++ b/frontend/src/components/object/share/ShareLinkContent.vue
@@ -30,7 +30,7 @@ const copyLinkToClipboard = () => {
       :value="props.shareLink"
     />
     <Button
-      class="p-button-outlined p-button-secondary"
+      class="p-button-outlined p-button-primary"
       @click="copyLinkToClipboard"
     >
       <font-awesome-icon
diff --git a/frontend/src/components/object/share/ShareObjectButton.vue b/frontend/src/components/object/share/ShareObjectButton.vue
index 69412085..6beba50e 100644
--- a/frontend/src/components/object/share/ShareObjectButton.vue
+++ b/frontend/src/components/object/share/ShareObjectButton.vue
@@ -90,7 +90,7 @@ onMounted(() => {
 
   <Button
     v-tooltip.bottom="'Share object'"
-    class="p-button-lg p-button-text"
+    class="p-button-lg p-button-text primary"
     aria-label="Share object"
     @click="displayShareDialog = true"
   >
diff --git a/frontend/src/views/HomeView.vue b/frontend/src/views/HomeView.vue
index 8c6d9951..c02f1bde 100644
--- a/frontend/src/views/HomeView.vue
+++ b/frontend/src/views/HomeView.vue
@@ -12,19 +12,16 @@ const { getConfig } = storeToRefs(useConfigStore());
 </script>
 
 <template>
-  <Message
-    v-if="getConfig?.notificationBanner"
-    severity="warn"
-  >
-    {{ getConfig?.notificationBanner }}
-  </Message>
-
-  <div class="flex flex-column mr-8 ml-8">
-    <div class="flex justify-content-center mb-5">
-      <h1>Store and share files in BCBox</h1>
-    </div>
-    <div class="flex justify-content-center mb-5">
-      <p class="text-xl text-center">
+  <div class="grid">
+    <div class="text-center">
+      <Message
+        v-if="getConfig?.notificationBanner"
+        severity="warn"
+      >
+        {{ getConfig?.notificationBanner }}
+      </Message>
+      <h1 class="mb-4">Store and share files in BCBox</h1>
+      <p class="text-xl">
         This website uses the
         <a href="https://bcgov.github.io/common-service-showcase/services/coms.html">
           Common Object Management Service
@@ -50,49 +47,36 @@ const { getConfig } = storeToRefs(useConfigStore());
         If you already have a bucket from outside of BCBox, you can't yet work on existing files from that bucket in
         BCBox, but we are currently working to make this possible through synchronization.
       </p>
-    </div>
-    <div class="flex justify-content-center mb-5">
-      <router-link
-        :to="{ name: RouteNames.LIST_BUCKETS }"
-        class="no-underline"
-      >
-        <Button>
-          {{ getIsAuthenticated ? 'Go to My Buckets' : 'Log in to get started' }}
-        </Button>
-      </router-link>
-    </div>
-    <div class="flex justify-content-center mb-8">
-      <img
-        src="@/assets/images/home_1.png"
-        class="border-1 drop-shadow"
-        width="60%"
-        alt="Screenshot of BCBox's file list interface:
+
+      <div class="flex flex-column justify-content-center align-items-center mb-4">
+        <router-link :to="{ name: RouteNames.LIST_BUCKETS }">
+          <Button>
+            {{ getIsAuthenticated ? 'Go to My Buckets' : 'Log in to get started' }}
+          </Button>
+        </router-link>
+
+        <img
+          src="@/assets/images/home_1.png"
+          class="border-1 drop-shadow w-8 sm:col-10 mt-5 mb-8 flex align-items-center"
+          alt="Screenshot of BCBox's file list interface:
             a list of example files and possible actions including Upload, Download and Delete."
-      />
-    </div>
-    <div class="flex justify-content-center mb-5">
-      <h2>Ongoing feature enhancements</h2>
-    </div>
-    <div class="flex justify-content-center mb-8 text-xl">
-      <ul>
-        <li>
+        />
+        <h2 class="mb-4">Ongoing feature enhancements</h2>
+
+        <p class="text-xl">
           BCBox is constantly improving! See BCBox's
           <a href="https://github.com/bcgov/bcbox/wiki">Help</a>
           for more information, a link to our Product Roadmap, and documentation of features as they are implemented.
-        </li>
-      </ul>
-    </div>
-    <div class="grid mb-8">
-      <div class="col-6 pr-5">
-        <div class="flex align-items-left mb-2">
-          <h2>Upload and download objects</h2>
-        </div>
-        <div class="flex align-items-left">
+        </p>
+      </div>
+
+      <div class="grid mb-8 text-left">
+        <div class="col-6 pr-5">
+          <h3 class="mb-3">Upload and download objects</h3>
           <p class="text-xl">With BCBox, you can use low-cost object storage for your files, images and documents.</p>
         </div>
-      </div>
-      <div class="col-6 pl-5">
-        <div class="flex align-items-center">
+
+        <div class="col-6">
           <img
             src="@/assets/images/home_2.png"
             class="border-1 drop-shadow"
@@ -101,13 +85,10 @@ const { getConfig } = storeToRefs(useConfigStore());
           />
         </div>
       </div>
-    </div>
-    <div class="grid mb-8">
-      <div class="col-6 pr-5">
-        <div class="flex align-items-left mb-2">
-          <h2>Manage access and share</h2>
-        </div>
-        <div class="flex align-items-left">
+
+      <div class="grid mb-4 text-left">
+        <div class="col-6 pr-5">
+          <h3 class="mb-3">Manage access and share</h3>
           <p class="text-xl">
             You can assign custom permissions to other users through IDIR or BCeID authentication.
             <br />
@@ -117,24 +98,20 @@ const { getConfig } = storeToRefs(useConfigStore());
             information without the consent of your Ministry Privacy Officer.
           </p>
         </div>
-      </div>
-      <div class="col-6 pl-5">
-        <div class="flex">
+        <div class="col-6">
           <img
             src="@/assets/images/home_3.png"
             class="border-1 drop-shadow"
             alt="Screenshot of BCBox's share interface,
-                  demonstrating a share link and QR code."
+                    demonstrating a share link and QR code."
           />
         </div>
       </div>
-    </div>
-    <div class="flex justify-content-center mb-5">
-      <h2>Versioning, metadata, tagging, syncing with existing buckets and more</h2>
-    </div>
-    <div class="flex justify-content-center mb-8 text-xl">
-      <ul>
-        <li>
+
+      <div class="flex flex-column justify-content-center align-items-center">
+        <h3 class="mb-4">Versioning, metadata, tagging, syncing with existing buckets and more</h3>
+
+        <p class="text-xl">
           Contact
           <a
             href="https://apps.nrs.gov.bc.ca/int/jira/servicedesk/customer/portal/1/create/701"
@@ -143,82 +120,77 @@ const { getConfig } = storeToRefs(useConfigStore());
             NRIDS Optimization
           </a>
           or your ministry's service desk. You will need a bucket to get started.
-        </li>
-      </ul>
-    </div>
-    <div class="flex justify-content-center mb-8">
-      <router-link
-        :to="{ name: RouteNames.LIST_BUCKETS }"
-        class="no-underline"
-      >
-        <Button>
-          {{ getIsAuthenticated ? 'Go to My Buckets' : 'Log in to get started' }}
-        </Button>
-      </router-link>
-    </div>
-    <div class="flex justify-content-center mb-5">
-      <h2>Terms of Use</h2>
-    </div>
-    <div class="flex justify-content-left mb-5 text-xl">
-      <ul>
-        <li>
-          It is your responsibility to comply with the
-          <a
-            href="https://www.bclaws.gov.bc.ca/civix/document/id/complete/statreg/96165_03#part3"
-            target="_blank"
-          >
-            Freedom of Information and Protection of Privacy Act
-          </a>
-          governing the collection, use and disclosure of personally identifiable information
-        </li>
-        <li>
-          Access to this tool does not inherently grant permission to collect, use or disclose any personally
-          identifiable information
-        </li>
-        <li>
-          It is your responsibility to provide a Collection Notice to individuals before collecting personally
-          identifiable information, as required by law
-        </li>
-        <li>
-          Before uploading and distributing files you are required to discuss your privacy intentions with your
-          <a
-            href="https://www2.gov.bc.ca/gov/content/governments/services-for-government/information-management-technology/privacy/resources/privacy-officers"
-            target="_blank"
-          >
-            Ministry Privacy Officer
-          </a>
-          and to complete assessments as required
-        </li>
-        <li>
-          If you intend to advise users to access with BCeID, please send an email to the
-          <a href="mailto:IDIM.Consulting@gov.bc.ca">Provincial Identity Information Management Program</a>
-          indicating your BCeID-related intentions
-        </li>
-        <li>
-          All other inquiries around getting or using buckets should be directed to
-          <a
-            href="https://apps.nrs.gov.bc.ca/int/jira/servicedesk/customer/portal/1/create/701"
-            target="_blank"
-          >
-            NRIDS Optimization
-          </a>
-          (Natural Resource ministries) or your ministry's service desk
-        </li>
-        <li>
-          Storage and custodianship of metadata and tags (not the objects themselves in your bucket) is maintained by
-          Natural Resource Information & Digital Services
-        </li>
-        <li>
-          You will refer to and adhere to
-          <a
-            href="https://www2.gov.bc.ca/gov/content/data/about-data-management/databc"
-            target="_blank"
-          >
-            DataBC
-          </a>
-          requirements for public file sharing
-        </li>
-      </ul>
+        </p>
+
+        <router-link :to="{ name: RouteNames.LIST_BUCKETS }">
+          <Button>
+            {{ getIsAuthenticated ? 'Go to My Buckets' : 'Log in to get started' }}
+          </Button>
+        </router-link>
+
+        <h2 class="mt-8 mb-4">Terms of Use</h2>
+        <div class="text-left text-xl">
+          <ul>
+            <li>
+              It is your responsibility to comply with the
+              <a
+                href="https://www.bclaws.gov.bc.ca/civix/document/id/complete/statreg/96165_03#part3"
+                target="_blank"
+              >
+                Freedom of Information and Protection of Privacy Act
+              </a>
+              governing the collection, use and disclosure of personally identifiable information
+            </li>
+            <li>
+              Access to this tool does not inherently grant permission to collect, use or disclose any personally
+              identifiable information
+            </li>
+            <li>
+              It is your responsibility to provide a Collection Notice to individuals before collecting personally
+              identifiable information, as required by law
+            </li>
+            <li>
+              Before uploading and distributing files you are required to discuss your privacy intentions with your
+              <a
+                href="https://www2.gov.bc.ca/gov/content/governments/services-for-government/information-management-technology/privacy/resources/privacy-officers"
+                target="_blank"
+              >
+                Ministry Privacy Officer
+              </a>
+              and to complete assessments as required
+            </li>
+            <li>
+              If you intend to advise users to access with BCeID, please send an email to the
+              <a href="mailto:IDIM.Consulting@gov.bc.ca">Provincial Identity Information Management Program</a>
+              indicating your BCeID-related intentions
+            </li>
+            <li>
+              All other inquiries around getting or using buckets should be directed to
+              <a
+                href="https://apps.nrs.gov.bc.ca/int/jira/servicedesk/customer/portal/1/create/701"
+                target="_blank"
+              >
+                NRIDS Optimization
+              </a>
+              (Natural Resource ministries) or your ministry's service desk
+            </li>
+            <li>
+              Storage and custodianship of metadata and tags (not the objects themselves in your bucket) is maintained
+              by Natural Resource Information & Digital Services
+            </li>
+            <li>
+              You will refer to and adhere to
+              <a
+                href="https://www2.gov.bc.ca/gov/content/data/about-data-management/databc"
+                target="_blank"
+              >
+                DataBC
+              </a>
+              requirements for public file sharing
+            </li>
+          </ul>
+        </div>
+      </div>
     </div>
   </div>
 </template>
@@ -227,4 +199,7 @@ const { getConfig } = storeToRefs(useConfigStore());
 img {
   max-width: 100%;
 }
+ul li {
+  margin-bottom: 1rem;
+}
 </style>
diff --git a/frontend/tests/unit/components/layout/Footer.spec.ts b/frontend/tests/unit/components/layout/Footer.spec.ts
index 1a8548b5..140755e7 100644
--- a/frontend/tests/unit/components/layout/Footer.spec.ts
+++ b/frontend/tests/unit/components/layout/Footer.spec.ts
@@ -40,14 +40,14 @@ describe('Footer.vue', () => {
     expect(wrapper).toBeTruthy();
   });
 
-  it('contains 7 buttons', () => {
+  it('contains 7 links', () => {
     const wrapper = mount(Footer, {
       global: {
         plugins: [createTestingPinia(), PrimeVue]
       }
     });
 
-    const btn = wrapper.findAll('button');
-    expect(btn).toHaveLength(7);
+    const links = wrapper.findAll('a');
+    expect(links).toHaveLength(7);
   });
 });