Improved styling.
Build and Deploy Web App / build-and-deploy (push) Successful in 20s Details

This commit is contained in:
andrewlalis 2025-09-07 09:46:48 -04:00
parent e5a8b94211
commit cf679c1c6e
14 changed files with 106 additions and 135 deletions

View File

@ -1,43 +1,28 @@
@import url('styles/text.css'); @import url('@/assets/styles/fonts.css');
@import url('@/assets/styles/text.css');
:root { :root {
--theme-primary: #01bbff; --theme-primary: #113188;
--theme-secondary: #00759f; --theme-secondary: #3b6bd3;
--theme-tertiary: #01ffc4; --theme-tertiary: #01ffc4;
--bg-primary: #00131a;
--bg-secondary: #003447; --bg: rgb(20, 20, 20);
--bg-page: #000b0f; --bg-darker: rgb(0, 0, 0);
--bg-lighter: rgb(41, 41, 41);
--text: rgb(247, 247, 247); --text: rgb(247, 247, 247);
--text-muted: gray; --text-muted: gray;
--positive: rgb(30, 197, 14); --positive: rgb(59, 219, 44);
--negative: rgb(253, 28, 28); --negative: rgb(253, 52, 52);
} --warning: rgb(255, 187, 0);
@font-face {
font-family: 'OpenSans';
src: url('fonts/open-sans/OpenSans-VariableFont_wdth,wght.woff2');
font-style: normal;
}
@font-face {
font-family: 'OpenSans';
src: url('fonts/open-sans/OpenSans-Italic-VariableFont_wdth,wght.woff2');
font-style: italic;
}
@font-face {
font-family: 'PlaywriteNL';
src: url('fonts/playwrite-nl/PlaywriteNL-VariableFont_wght.woff2');
font-style: italic;
} }
body { body {
padding: 0; padding: 0;
margin: 0; margin: 0;
font-family: 'OpenSans', sans-serif; font-family: 'OpenSans', sans-serif;
background-color: var(--bg-primary); background-color: var(--bg);
color: var(--theme-primary); color: var(--text);
} }
a { a {

View File

@ -0,0 +1,17 @@
@font-face {
font-family: 'OpenSans';
src: url('@/assets/fonts/open-sans/OpenSans-VariableFont_wdth,wght.woff2');
font-style: normal;
}
@font-face {
font-family: 'OpenSans';
src: url('@/assets/fonts/open-sans/OpenSans-Italic-VariableFont_wdth,wght.woff2');
font-style: italic;
}
@font-face {
font-family: 'PlaywriteNL';
src: url('@/assets/fonts/playwrite-nl/PlaywriteNL-VariableFont_wght.woff2');
font-style: italic;
}

View File

@ -4,6 +4,7 @@ import { formatMoney } from '@/api/data';
import { getSelectedProfile } from '@/api/profile'; import { getSelectedProfile } from '@/api/profile';
import { computed } from 'vue'; import { computed } from 'vue';
import { useRoute, useRouter } from 'vue-router'; import { useRoute, useRouter } from 'vue-router';
import AppBadge from './common/AppBadge.vue';
const router = useRouter() const router = useRouter()
const route = useRoute() const route = useRoute()
@ -35,13 +36,13 @@ function goToAccount() {
<!-- A top row for the name on the left, and balance on the right. --> <!-- A top row for the name on the left, and balance on the right. -->
<div class="account-card-top-row"> <div class="account-card-top-row">
<div> <div>
<span class="account-card-name">{{ account.name }}</span> <span class="font-bold" style="margin-right: 0.5rem">{{ account.name }}</span>
<span class="account-card-number-suffix">#{{ account.numberSuffix }}</span> <span class="font-mono font-size-xsmall">#{{ account.numberSuffix }}</span>
</div> </div>
<div class="account-card-balance" :class="{ <div class="font-mono font-size-small" :class="{
'account-card-balance-positive': isBalancePositive, 'text-positive': isBalancePositive,
'account-card-balance-negative': isBalanceNegative 'text-negative': isBalanceNegative
}"> }">
<span v-if="account.currentBalance !== null"> <span v-if="account.currentBalance !== null">
{{ formatMoney(account.currentBalance, account.currency) }} {{ formatMoney(account.currentBalance, account.currency) }}
@ -52,15 +53,13 @@ function goToAccount() {
</div> </div>
<!-- A bottom row for other attributes. --> <!-- A bottom row for other attributes. -->
<div> <div>
<span class="account-card-badge"> <AppBadge size="sm">{{ accountType.name }}</AppBadge>
{{ accountType.name }}
</span>
</div> </div>
</div> </div>
</template> </template>
<style lang="css"> <style lang="css">
.account-card { .account-card {
background-color: var(--bg-primary); background-color: var(--bg);
padding: 0.5rem; padding: 0.5rem;
border-radius: 0.5rem; border-radius: 0.5rem;
margin: 0.5rem 0; margin: 0.5rem 0;
@ -68,43 +67,11 @@ function goToAccount() {
} }
.account-card:hover { .account-card:hover {
background-color: var(--bg-page); background-color: var(--bg-darker);
} }
.account-card-top-row { .account-card-top-row {
display: flex; display: flex;
justify-content: space-between; justify-content: space-between;
} }
.account-card-name {
font-size: 1rem;
font-weight: 600;
margin-right: 0.5rem;
}
.account-card-number-suffix {
font-size: 0.8rem;
font-family: monospace;
}
.account-card-balance {
font-size: 0.9rem;
font-family: monospace;
color: white;
}
.account-card-balance-positive {
color: green;
}
.account-card-balance-negative {
color: red;
}
.account-card-badge {
font-size: 0.75rem;
padding: 0.1rem 0.25rem;
background-color: var(--bg-secondary);
border-radius: 0.3rem;
}
</style> </style>

View File

@ -69,10 +69,10 @@ const canExpand = computed(() => props.category.children.length > 0)
} }
.category-display-item-bg-1 { .category-display-item-bg-1 {
background-color: var(--bg-primary); background-color: var(--bg);
} }
.category-display-item-bg-2 { .category-display-item-bg-2 {
background-color: var(--bg-secondary); background-color: var(--bg-lighter);
} }
</style> </style>

View File

@ -1,6 +1,7 @@
<script setup lang="ts"> <script setup lang="ts">
import { getSelectedProfile } from '@/api/profile'; import { getSelectedProfile } from '@/api/profile';
import { useRoute, useRouter } from 'vue-router'; import { useRoute, useRouter } from 'vue-router';
import AppBadge from './common/AppBadge.vue';
interface CategoryInfo { interface CategoryInfo {
name: string name: string
@ -19,20 +20,12 @@ function onClicked() {
} }
</script> </script>
<template> <template>
<span class="category-label" @click="onClicked()" :style="{ 'cursor': clickable ? 'pointer' : 'inherit' }"> <AppBadge @click="onClicked()" :style="{ 'cursor': clickable ? 'pointer' : 'inherit' }">
<div class="category-label-color" :style="{ 'background-color': '#' + category.color }"></div> <div class="category-label-color" :style="{ 'background-color': '#' + category.color }"></div>
{{ category.name }} {{ category.name }}
</span> </AppBadge>
</template> </template>
<style lang="css"> <style lang="css">
.category-label {
margin: 0.25rem;
padding: 0.1rem 0.25rem;
background-color: var(--bg-secondary);
border-radius: 0.4rem;
font-size: 14px;
}
.category-label-color { .category-label-color {
width: 0.75rem; width: 0.75rem;
height: 0.75rem; height: 0.75rem;

View File

@ -20,7 +20,7 @@ defineProps<{ title: string }>()
min-width: 300px; min-width: 300px;
min-height: 200px; min-height: 200px;
flex-grow: 1; flex-grow: 1;
background-color: var(--bg-secondary); background-color: var(--bg-lighter);
border-radius: 0.5rem; border-radius: 0.5rem;
padding: 0.5rem; padding: 0.5rem;
display: flex; display: flex;

View File

@ -1,31 +1,25 @@
<script setup lang="ts"> <script setup lang="ts">
import AppBadge from './common/AppBadge.vue';
defineProps<{ tag: string, deletable?: boolean }>() defineProps<{ tag: string, deletable?: boolean }>()
defineEmits<{ deleted: void }>() defineEmits<{ deleted: void }>()
</script> </script>
<template> <template>
<span class="tag-label"> <AppBadge>
<span class="tag-label-hashtag">#</span> <span class="tag-label-hashtag">#</span>
{{ tag }} {{ tag }}
<font-awesome-icon v-if="deletable" icon="fa-x" class="tag-label-delete" <font-awesome-icon v-if="deletable" icon="fa-x" class="tag-label-delete"
@click="$emit('deleted')"></font-awesome-icon> @click="$emit('deleted')"></font-awesome-icon>
</span> </AppBadge>
</template> </template>
<style lang="css"> <style lang="css">
.tag-label {
margin: 0.25rem;
padding: 0.1rem 0.25rem;
background-color: var(--bg-secondary);
border-radius: 0.4rem;
font-size: 14px;
}
.tag-label-hashtag { .tag-label-hashtag {
color: rgb(82, 82, 102); color: var(--text-muted);
margin-right: -0.2rem; margin-right: -0.2rem;
} }
.tag-label-delete { .tag-label-delete {
color: gray; color: var(--text-muted);
cursor: pointer; cursor: pointer;
} }
</style> </style>

View File

@ -5,6 +5,7 @@ import type { TransactionsListItem } from '@/api/transaction';
import { useRoute, useRouter } from 'vue-router'; import { useRoute, useRouter } from 'vue-router';
import CategoryLabel from './CategoryLabel.vue'; import CategoryLabel from './CategoryLabel.vue';
import { computed, type Ref } from 'vue'; import { computed, type Ref } from 'vue';
import AppBadge from './common/AppBadge.vue';
const router = useRouter() const router = useRouter()
const route = useRoute() const route = useRoute()
@ -61,13 +62,13 @@ function goToTransaction() {
<!-- Bottom row contains other links. --> <!-- Bottom row contains other links. -->
<div> <div>
<CategoryLabel :category="tx.category" v-if="tx.category" style="margin-left: 0" /> <CategoryLabel :category="tx.category" v-if="tx.category" style="margin-left: 0" />
<span class="transaction-card-vendor-label" v-if="tx.vendor">{{ tx.vendor.name }}</span> <AppBadge v-if="tx.vendor">{{ tx.vendor.name }}</AppBadge>
</div> </div>
</div> </div>
</template> </template>
<style lang="css"> <style lang="css">
.transaction-card { .transaction-card {
background-color: var(--bg-primary); background-color: var(--bg);
padding: 0.5rem; padding: 0.5rem;
border-radius: 0.5rem; border-radius: 0.5rem;
margin: 0.5rem 0; margin: 0.5rem 0;
@ -75,7 +76,7 @@ function goToTransaction() {
} }
.transaction-card:hover { .transaction-card:hover {
background-color: var(--bg-page); background-color: var(--bg-darker);
} }
.transaction-card-top-row { .transaction-card-top-row {
@ -87,12 +88,4 @@ function goToTransaction() {
margin: 0.25rem 0; margin: 0.25rem 0;
font-size: 0.9rem; font-size: 0.9rem;
} }
.transaction-card-vendor-label {
background-color: var(--bg-secondary);
border-radius: 0.3rem;
padding: 0.1rem 0.2rem;
font-size: 0.9rem;
}
</style> </style>

View File

@ -0,0 +1,39 @@
<script setup lang="ts">
type BadgeSize = "sm" | "md" | "lg";
type BadgeStyle = "normal" | "positive" | "warning" | "negative"
defineProps<{ size?: BadgeSize, color?: BadgeStyle }>()
</script>
<template>
<span class="app-badge" :class="{
'app-badge-sm': size === 'sm',
'app-badge-lg': size === 'lg'
}">
<slot></slot>
</span>
</template>
<style lang="css">
.app-badge {
padding: 0.1rem 0.5rem;
border-radius: 0.5rem;
background-color: var(--bg-lighter);
font-size: 0.9rem;
border: 1px solid var(--text-muted);
}
.app-badge+.app-badge {
margin-left: 0.25rem;
}
.app-badge-sm {
padding: 0.1rem 0.25rem;
border-radius: 0.3rem;
font-size: 0.75rem;
}
.app-badge-lg {
padding: 0.3rem 0.6rem;
border-radius: 0.6rem;
font-size: 1rem;
}
</style>

View File

@ -14,7 +14,7 @@ defineProps<{ title: string }>()
margin-right: auto; margin-right: auto;
padding: 0.5rem; padding: 0.5rem;
padding-bottom: 1rem; padding-bottom: 1rem;
background-color: var(--bg-page); background-color: var(--bg-lighter);
border-bottom-left-radius: 2rem; border-bottom-left-radius: 2rem;
border-bottom-right-radius: 2rem; border-bottom-right-radius: 2rem;

View File

@ -37,7 +37,7 @@ defineExpose({ show, close })
</template> </template>
<style lang="css"> <style lang="css">
.app-modal-dialog { .app-modal-dialog {
background-color: var(--bg-secondary); background-color: var(--bg-lighter);
color: inherit; color: inherit;
border-radius: 1rem; border-radius: 1rem;
border-width: 0; border-width: 0;

View File

@ -39,7 +39,7 @@ function asJE(i: AccountHistoryItem): AccountHistoryJournalEntryItem {
<div> <div>
<div v-for="item in historyItems" :key="item.timestamp" class="history-item"> <div v-for="item in historyItems" :key="item.timestamp" class="history-item">
<div class="history-item-header"> <div class="history-item-header">
<div class="history-item-header-timestamp">{{ new Date(item.timestamp).toLocaleString() }}</div> <div class="font-mono font-size-xsmall">{{ new Date(item.timestamp).toLocaleString() }}</div>
<div>{{ item.type }}</div> <div>{{ item.type }}</div>
</div> </div>
@ -55,7 +55,7 @@ function asJE(i: AccountHistoryItem): AccountHistoryJournalEntryItem {
margin-top: 1rem; margin-top: 1rem;
margin-bottom: 1rem; margin-bottom: 1rem;
padding: 0.25rem 1rem; padding: 0.25rem 1rem;
background-color: var(--bg-secondary); background-color: var(--bg-lighter);
border-radius: 1rem; border-radius: 1rem;
} }
@ -64,11 +64,6 @@ function asJE(i: AccountHistoryItem): AccountHistoryJournalEntryItem {
text-align: right; text-align: right;
} }
.history-item-header-timestamp {
font-family: monospace;
font-size: 12px;
}
.history-item-content { .history-item-content {
padding: 0.5rem 0; padding: 0.5rem 0;
} }

View File

@ -69,7 +69,7 @@ async function addProfile() {
display: flex; display: flex;
justify-content: space-between; justify-content: space-between;
padding: 0.5em; padding: 0.5em;
background-color: var(--bg-secondary); background-color: var(--bg);
border-radius: 1em; border-radius: 1em;
margin-top: 1em; margin-top: 1em;
margin-bottom: 1em; margin-bottom: 1em;
@ -77,6 +77,6 @@ async function addProfile() {
} }
.profile-card:hover { .profile-card:hover {
background-color: var(--bg-primary); background-color: var(--bg-darker);
} }
</style> </style>

View File

@ -81,7 +81,7 @@ async function checkAuth() {
<style lang="css"> <style lang="css">
.app-header-bar { .app-header-bar {
background-color: var(--theme-primary); background-color: var(--theme-primary);
color: var(--bg-primary); color: var(--text);
display: flex; display: flex;
justify-content: space-between; justify-content: space-between;
align-items: center; align-items: center;
@ -97,42 +97,30 @@ async function checkAuth() {
} }
.app-header-text:hover { .app-header-text:hover {
color: var(--theme-secondary); color: var(--text-muted);
} }
.app-logout-button { .app-logout-button {
cursor: pointer; cursor: pointer;
margin-right: 0.5em; margin-right: 0.5em;
background-color: #0099d1; background-color: var(--theme-secondary);
border-radius: 50%; border-radius: 50%;
padding: 0.35rem; padding: 0.35rem;
} }
.app-logout-button:hover { .app-logout-button:hover {
color: var(--bg-secondary); color: var(--text-muted);
} }
.app-user-widget { .app-user-widget {
margin-right: 0.5em; margin-right: 0.5em;
cursor: pointer; cursor: pointer;
background-color: #0099d1; background-color: var(--theme-secondary);
border-radius: 50%; border-radius: 50%;
padding: 0.35rem; padding: 0.35rem;
} }
.app-user-widget:hover { .app-user-widget:hover {
color: var(--bg-secondary); color: var(--text-muted);
}
.app-header-link {
font-weight: bold;
color: var(--bg-primary);
text-decoration: none;
margin: 0 0.5em 0 0.5em;
}
.app-header-link:hover {
color: var(--bg-secondary);
text-decoration: underline;
} }
</style> </style>