diff --git a/CLAUDE.md b/CLAUDE.md
index f1e1746..879ed9e 100644
--- a/CLAUDE.md
+++ b/CLAUDE.md
@@ -29,3 +29,50 @@ Svelte 5 removed event modifiers like `on:click|preventDefault`. Use inline hand
Generates a Svelte Playground link with the provided code.
After completing the code, ask the user if they want a playground link. Only call this tool after user confirmation and NEVER if code was written to files in their project.
+
+## Theming Rules
+
+### Semantic CSS Variables (ALWAYS use these, NEVER hardcode Nord values for themed properties)
+
+| Purpose | Variable | Light resolves to | Dark resolves to |
+|---|---|---|---|
+| Page background | `--color-bg-primary` | white/light | dark |
+| Card/section bg | `--color-surface` | nord6-ish | nord1-ish |
+| Secondary bg | `--color-bg-secondary` | slightly darker | slightly lighter |
+| Tertiary bg (inputs, insets) | `--color-bg-tertiary` | nord5-ish | nord2-ish |
+| Hover/elevated bg | `--color-bg-elevated` | nord4-ish | nord3-ish |
+| Primary text | `--color-text-primary` | dark text | light text |
+| Secondary text (labels, muted) | `--color-text-secondary` | nord3 | nord4 |
+| Tertiary text (descriptions) | `--color-text-tertiary` | nord2 | nord5 |
+| Borders | `--color-border` | nord4 | nord2/3 |
+
+### What NOT to do
+- **NEVER** use `var(--nord0)` through `var(--nord6)` for backgrounds, text, or borders — these don't adapt to theme
+- **NEVER** write `@media (prefers-color-scheme: dark)` or `:global(:root[data-theme="dark"])` override blocks — semantic variables handle both themes automatically
+- **NEVER** use `var(--font-default-dark)` or `var(--accent-dark)` — these are legacy
+
+### Accent colors (OK to use directly, they work in both themes)
+- `var(--blue)`, `var(--red)`, `var(--green)`, `var(--orange)` — named accent colors
+- `var(--nord10)`, `var(--nord11)`, `var(--nord12)`, `var(--nord14)` — OK for hover states of accent-colored buttons only
+
+### Chart.js theme reactivity
+Charts don't use CSS variables. Use the `isDark()` pattern from `FitnessChart.svelte`:
+```js
+function isDark() {
+ const theme = document.documentElement.getAttribute('data-theme');
+ if (theme === 'dark') return true;
+ if (theme === 'light') return false;
+ return window.matchMedia('(prefers-color-scheme: dark)').matches;
+}
+const textColor = isDark() ? '#D8DEE9' : '#2E3440';
+```
+Re-create the chart on theme change via `MutationObserver` on `data-theme` + `matchMedia` listener.
+
+### Form inputs
+- Background: `var(--color-bg-tertiary)`
+- Border: `var(--color-border)`
+- Text: `var(--color-text-primary)`
+- Label: `var(--color-text-secondary)`
+
+### Toggle component
+Use `Toggle.svelte` (iOS-style) instead of raw ` ` for user-facing boolean switches.
diff --git a/src/lib/components/FormSection.svelte b/src/lib/components/FormSection.svelte
index 4b1f297..a966527 100644
--- a/src/lib/components/FormSection.svelte
+++ b/src/lib/components/FormSection.svelte
@@ -13,35 +13,17 @@
\ No newline at end of file
+
diff --git a/src/lib/components/ImageUpload.svelte b/src/lib/components/ImageUpload.svelte
index d5d61da..9aca6f9 100644
--- a/src/lib/components/ImageUpload.svelte
+++ b/src/lib/components/ImageUpload.svelte
@@ -61,7 +61,7 @@
{/if}
-
+
{#if imagePreview}
@@ -93,17 +93,17 @@
JPEG, PNG, WebP (max 5MB)
-
{/if}
-
+
{#if uploading}
Uploading image...
{/if}
@@ -111,114 +111,55 @@
\ No newline at end of file
+
diff --git a/src/lib/components/SaveFab.svelte b/src/lib/components/SaveFab.svelte
new file mode 100644
index 0000000..b2e63d0
--- /dev/null
+++ b/src/lib/components/SaveFab.svelte
@@ -0,0 +1,51 @@
+
+
+
+
+
+
+
diff --git a/src/lib/components/cospend/BarChart.svelte b/src/lib/components/cospend/BarChart.svelte
index a3752d7..5ceb460 100644
--- a/src/lib/components/cospend/BarChart.svelte
+++ b/src/lib/components/cospend/BarChart.svelte
@@ -20,6 +20,13 @@
// Register Chart.js components
Chart.register(...registerables);
+ function isDark() {
+ const theme = document.documentElement.getAttribute('data-theme');
+ if (theme === 'dark') return true;
+ if (theme === 'light') return false;
+ return window.matchMedia('(prefers-color-scheme: dark)').matches;
+ }
+
// Nord theme colors for categories
const nordColors = [
'#5E81AC', // Nord Blue
@@ -82,6 +89,12 @@
const ctx = canvas.getContext('2d');
if (!ctx) return;
+ const dark = isDark();
+ const textColor = dark ? '#D8DEE9' : '#2E3440';
+ const tooltipBg = dark ? '#2E3440' : '#ECEFF4';
+ const tooltipText = dark ? '#ECEFF4' : '#2E3440';
+ const tooltipBody = dark ? '#D8DEE9' : '#3B4252';
+
// Convert $state proxy to plain arrays to avoid Chart.js property descriptor issues
const plainLabels = [...(data.labels || [])];
const plainDatasets = (data.datasets || []).map((/** @type {{ label: string, data: number[] }} */ ds) => ({
@@ -123,7 +136,7 @@
display: false
},
ticks: {
- color: '#ffffff',
+ color: textColor,
font: {
family: 'Inter, system-ui, sans-serif',
size: 14,
@@ -157,7 +170,7 @@
labels: {
padding: 20,
usePointStyle: true,
- color: '#ffffff',
+ color: textColor,
font: {
family: 'Inter, system-ui, sans-serif',
size: 14,
@@ -194,7 +207,7 @@
title: {
display: !!title,
text: title,
- color: '#ffffff',
+ color: textColor,
font: {
family: 'Inter, system-ui, sans-serif',
size: 18,
@@ -203,9 +216,9 @@
padding: 20
},
tooltip: {
- backgroundColor: '#2e3440',
- titleColor: '#ffffff',
- bodyColor: '#ffffff',
+ backgroundColor: tooltipBg,
+ titleColor: tooltipText,
+ bodyColor: tooltipBody,
borderWidth: 0,
cornerRadius: 12,
padding: 12,
@@ -275,7 +288,7 @@
ctx.save();
ctx.font = 'bold 14px Inter, system-ui, sans-serif';
- ctx.fillStyle = '#ffffff';
+ ctx.fillStyle = isDark() ? '#D8DEE9' : '#2E3440';
ctx.textAlign = 'center';
ctx.textBaseline = 'bottom';
@@ -367,24 +380,12 @@
\ No newline at end of file
+
diff --git a/src/lib/components/cospend/UsersList.svelte b/src/lib/components/cospend/UsersList.svelte
index 8475e03..ffd8fb9 100644
--- a/src/lib/components/cospend/UsersList.svelte
+++ b/src/lib/components/cospend/UsersList.svelte
@@ -14,10 +14,10 @@
canRemoveUsers?: boolean,
newUser?: string
}>();
-
+
function addUser() {
if (predefinedMode) return;
-
+
if (newUser.trim() && !users.includes(newUser.trim())) {
users = [...users, newUser.trim()];
newUser = '';
@@ -36,7 +36,7 @@
Split Between Users
-
+
{#if predefinedMode}
Splitting between predefined users:
@@ -84,38 +84,20 @@
\ No newline at end of file
+
diff --git a/src/routes/[recipeLang=recipeLang]/edit/[name]/+page.svelte b/src/routes/[recipeLang=recipeLang]/edit/[name]/+page.svelte
index 5e3ba85..3e5f605 100644
--- a/src/routes/[recipeLang=recipeLang]/edit/[name]/+page.svelte
+++ b/src/routes/[recipeLang=recipeLang]/edit/[name]/+page.svelte
@@ -2,7 +2,7 @@
import { enhance } from '$app/forms';
import { tick } from 'svelte';
import type { ActionData, PageData } from './$types';
- import Check from '$lib/assets/icons/Check.svelte';
+ import SaveFab from '$lib/components/SaveFab.svelte';
import Cross from '$lib/assets/icons/Cross.svelte';
import SeasonSelect from '$lib/components/recipes/SeasonSelect.svelte';
import TranslationApproval from '$lib/components/recipes/TranslationApproval.svelte';
@@ -479,34 +479,6 @@
font-size: 1.3rem;
color: white;
}
- .fab-save {
- position: fixed;
- bottom: 0;
- right: 0;
- width: 1rem;
- height: 1rem;
- padding: 2rem;
- margin: 2rem;
- border-radius: var(--radius-pill);
- background-color: var(--red);
- display: grid;
- justify-content: center;
- align-content: center;
- z-index: 100;
- animation: unset !important;
- }
- .fab-save:hover, .fab-save:focus {
- background-color: var(--nord0) !important;
- }
- .fab-save:disabled {
- opacity: 0.5;
- cursor: not-allowed;
- }
- @media screen and (max-width: 500px) {
- .fab-save {
- margin: 1rem;
- }
- }
.submit_buttons {
display: flex;
margin-inline: auto;
@@ -1147,13 +1119,4 @@
{/if}
-
-
-
-
+
diff --git a/src/routes/cospend/+layout.svelte b/src/routes/cospend/+layout.svelte
index 95c98c9..7b09616 100644
--- a/src/routes/cospend/+layout.svelte
+++ b/src/routes/cospend/+layout.svelte
@@ -108,12 +108,13 @@
.side-panel {
position: fixed;
- top: 4rem;
+ top: 0;
right: 0;
width: 400px;
- height: calc(100vh - 4rem);
- background: #fbf9f3;
- border-left: 1px solid #dee2e6;
+ height: 100vh;
+ padding-top: var(--header-h, 3rem);
+ background: var(--color-bg-tertiary);
+ border-left: 1px solid var(--color-border);
box-shadow: -2px 0 10px rgba(0, 0, 0, 0.1);
z-index: 100;
overflow-y: auto;
@@ -139,17 +140,6 @@
overflow-y: auto;
}
- @media (prefers-color-scheme: dark) {
- :global(:root:not([data-theme="light"])) .side-panel {
- background: var(--background-dark);
- border-left-color: #434C5E;
- }
- }
-:global(:root[data-theme="dark"]) .side-panel {
- background: var(--background-dark);
- border-left-color: #434C5E;
-}
-
@media (max-width: 768px) {
.layout-container.has-modal .main-content {
margin-right: 0;
@@ -157,11 +147,12 @@
.side-panel {
position: fixed;
- top: 4rem;
+ top: 0;
left: 0;
right: 0;
width: 100%;
- height: calc(100vh - 4rem);
+ height: 100vh;
+ padding-top: var(--header-h, 3rem);
transform: translateY(100%);
}
@@ -188,8 +179,9 @@
min-width: unset;
max-width: unset;
width: 100%;
+ padding-top: 0;
border-left: none;
- border-top: 1px solid #dee2e6;
+ border-top: 1px solid var(--color-border);
box-shadow: 0 -2px 10px rgba(0, 0, 0, 0.1);
top: auto;
bottom: 0;
@@ -200,15 +192,4 @@
transform: translateY(0);
}
}
-
- @media (max-width: 768px) and (prefers-color-scheme: dark) {
- .side-panel {
- border-top-color: #434C5E;
- }
- }
-@media (max-width: 768px) {
- :global(:root[data-theme="dark"]) .side-panel {
- border-top-color: #434C5E;
-}
-}
diff --git a/src/routes/cospend/+page.svelte b/src/routes/cospend/+page.svelte
index 692756d..00688ee 100644
--- a/src/routes/cospend/+page.svelte
+++ b/src/routes/cospend/+page.svelte
@@ -310,7 +310,7 @@
text-align: center;
font-size: 2.5rem;
margin-block: 0.5rem 1.5rem;
- color: var(--nord0);
+ color: var(--color-text-primary);
}
.loading, .error {
@@ -321,26 +321,10 @@
.error {
color: var(--red);
- background-color: var(--nord6);
+ background-color: var(--color-bg-secondary);
border-radius: 0.5rem;
}
- @media (prefers-color-scheme: dark) {
- :global(:root:not([data-theme="light"])) h1 {
- color: var(--font-default-dark);
- }
-
- :global(:root:not([data-theme="light"])) .error {
- background-color: var(--accent-dark);
- }
- }
-:global(:root[data-theme="dark"]) h1 {
- color: var(--font-default-dark);
-}
-:global(:root[data-theme="dark"]) .error {
- background-color: var(--accent-dark);
-}
-
.positive {
color: var(--green);
@@ -379,11 +363,7 @@
}
.recent-activity {
- background: var(--nord6);
- padding: 1.5rem;
- border-radius: 0.75rem;
- box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
- border: 1px solid var(--nord4);
+ padding: 1.5rem 0;
max-width: 800px;
margin-left: auto;
margin-right: auto;
@@ -399,21 +379,21 @@
.recent-activity h2 {
margin: 0;
- color: var(--nord0);
+ color: var(--color-text-primary);
}
.filter-label {
font-weight: 400;
font-size: 1rem;
- color: var(--nord3);
+ color: var(--color-text-secondary);
}
.clear-filter {
background: none;
- border: 1px solid var(--nord4);
+ border: 1px solid var(--color-border);
border-radius: 0.5rem;
padding: 0.25rem 0.75rem;
- color: var(--nord3);
+ color: var(--color-text-secondary);
cursor: pointer;
font-size: 0.85rem;
white-space: nowrap;
@@ -421,67 +401,17 @@
}
.clear-filter:hover {
- border-color: var(--blue);
- color: var(--blue);
+ border-color: var(--color-primary);
+ color: var(--color-primary);
}
.no-results {
text-align: center;
- color: var(--nord3);
+ color: var(--color-text-secondary);
font-style: italic;
padding: 1rem 0;
}
- @media (prefers-color-scheme: dark) {
- :global(:root:not([data-theme="light"])) .recent-activity {
- background: var(--accent-dark);
- border-color: var(--nord2);
- }
-
- :global(:root:not([data-theme="light"])) .recent-activity h2 {
- color: var(--font-default-dark);
- }
-
- :global(:root:not([data-theme="light"])) .filter-label {
- color: var(--nord4);
- }
-
- :global(:root:not([data-theme="light"])) .clear-filter {
- border-color: var(--nord3);
- color: var(--nord4);
- }
-
- :global(:root:not([data-theme="light"])) .clear-filter:hover {
- border-color: var(--blue);
- color: var(--blue);
- }
-
- :global(:root:not([data-theme="light"])) .no-results {
- color: var(--nord4);
- }
- }
-:global(:root[data-theme="dark"]) .recent-activity {
- background: var(--accent-dark);
- border-color: var(--nord2);
-}
-:global(:root[data-theme="dark"]) .recent-activity h2 {
- color: var(--font-default-dark);
-}
-:global(:root[data-theme="dark"]) .filter-label {
- color: var(--nord4);
-}
-:global(:root[data-theme="dark"]) .clear-filter {
- border-color: var(--nord3);
- color: var(--nord4);
-}
-:global(:root[data-theme="dark"]) .clear-filter:hover {
- border-color: var(--blue);
- color: var(--blue);
-}
-:global(:root[data-theme="dark"]) .no-results {
- color: var(--nord4);
-}
-
.activity-dialog {
display: flex;
flex-direction: column;
@@ -511,11 +441,11 @@
}
.activity-bubble {
- background: var(--nord5);
+ background: var(--color-bg-secondary);
border-radius: 1rem;
padding: 1rem;
position: relative;
- border: 1px solid var(--nord4);
+ border: none;
text-decoration: none;
color: inherit;
display: block;
@@ -524,30 +454,9 @@
}
.activity-message.is-me .activity-bubble {
- background: var(--nord8);
- border-color: var(--blue);
+ background: var(--color-bg-tertiary);
}
- @media (prefers-color-scheme: dark) {
- :global(:root:not([data-theme="light"])) .activity-bubble {
- background: var(--nord1);
- border-color: var(--nord2);
- }
-
- :global(:root:not([data-theme="light"])) .activity-message.is-me .activity-bubble {
- background: var(--nord2);
- border-color: var(--blue);
- }
- }
-:global(:root[data-theme="dark"]) .activity-bubble {
- background: var(--nord1);
- border-color: var(--nord2);
-}
-:global(:root[data-theme="dark"]) .activity-message.is-me .activity-bubble {
- background: var(--nord2);
- border-color: var(--blue);
-}
-
.activity-bubble:hover {
transform: translateY(-1px);
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.15);
@@ -564,39 +473,23 @@
.activity-bubble::before {
left: -15px;
- border-right-color: var(--nord5);
+ border-right-color: var(--color-bg-secondary);
}
.activity-message.is-me .activity-bubble::before {
left: auto;
right: -15px;
- border-left-color: var(--nord8);
+ border-left-color: var(--color-bg-tertiary);
border-right-color: transparent;
}
- @media (prefers-color-scheme: dark) {
- :global(:root:not([data-theme="light"])) .activity-bubble::before {
- border-right-color: var(--nord1);
- }
- :global(:root:not([data-theme="light"])) .activity-message.is-me .activity-bubble::before {
- border-left-color: var(--nord2);
- }
- }
-:global(:root[data-theme="dark"]) .activity-bubble::before {
- border-right-color: var(--nord1);
-}
-:global(:root[data-theme="dark"]) .activity-message.is-me .activity-bubble::before {
- border-left-color: var(--nord2);
-}
-
-
- /* New Settlement Flow Activity Styles */
+ /* Settlement Flow Activity Styles */
.settlement-flow-activity {
display: block;
text-decoration: none;
color: inherit;
- background: linear-gradient(135deg, var(--nord6), var(--nord5));
+ background: var(--color-bg-secondary);
border: 2px solid var(--green);
border-radius: 1rem;
padding: 1.5rem;
@@ -610,24 +503,6 @@
transform: translateY(-2px);
}
- @media (prefers-color-scheme: dark) {
- :global(:root:not([data-theme="light"])) .settlement-flow-activity {
- background: linear-gradient(135deg, var(--nord2), var(--nord1));
- border-color: var(--green);
- }
-
- :global(:root:not([data-theme="light"])) .settlement-flow-activity:hover {
- box-shadow: 0 6px 20px rgba(163, 190, 140, 0.2);
- }
- }
-:global(:root[data-theme="dark"]) .settlement-flow-activity {
- background: linear-gradient(135deg, var(--nord2), var(--nord1));
- border-color: var(--green);
-}
-:global(:root[data-theme="dark"]) .settlement-flow-activity:hover {
- box-shadow: 0 6px 20px rgba(163, 190, 140, 0.2);
-}
-
.settlement-activity-content {
width: 100%;
}
@@ -677,19 +552,10 @@
.settlement-date {
font-size: 0.9rem;
- color: var(--nord3);
+ color: var(--color-text-secondary);
text-align: center;
}
- @media (prefers-color-scheme: dark) {
- :global(:root:not([data-theme="light"])) .settlement-date {
- color: var(--nord4);
- }
- }
-:global(:root[data-theme="dark"]) .settlement-date {
- color: var(--nord4);
-}
-
.activity-header {
display: flex;
justify-content: space-between;
@@ -715,47 +581,24 @@
}
.category-name {
- color: var(--nord3);
+ color: var(--color-text-tertiary);
font-size: 0.8rem;
font-style: italic;
}
.payment-title {
- color: var(--nord0);
+ color: var(--color-text-primary);
font-size: 1.1rem;
font-weight: 600;
margin: 0;
}
.username {
- color: var(--nord3);
+ color: var(--color-text-secondary);
font-size: 0.9rem;
font-weight: 500;
}
- @media (prefers-color-scheme: dark) {
- :global(:root:not([data-theme="light"])) .category-name {
- color: var(--nord4);
- }
-
- :global(:root:not([data-theme="light"])) .payment-title {
- color: var(--font-default-dark);
- }
-
- :global(:root:not([data-theme="light"])) .username {
- color: var(--nord4);
- }
- }
-:global(:root[data-theme="dark"]) .category-name {
- color: var(--nord4);
-}
-:global(:root[data-theme="dark"]) .payment-title {
- color: var(--font-default-dark);
-}
-:global(:root[data-theme="dark"]) .username {
- color: var(--nord4);
-}
-
.activity-amount {
font-weight: bold;
font-size: 1rem;
@@ -775,34 +618,18 @@
}
.payment-date {
- color: var(--nord3);
+ color: var(--color-text-secondary);
font-size: 0.9rem;
}
.payment-description {
- color: var(--nord2);
+ color: var(--color-text-tertiary);
font-size: 0.9rem;
font-style: italic;
margin-top: 0.25rem;
line-height: 1.3;
}
- @media (prefers-color-scheme: dark) {
- :global(:root:not([data-theme="light"])) .payment-date {
- color: var(--nord4);
- }
-
- :global(:root:not([data-theme="light"])) .payment-description {
- color: var(--nord5);
- }
- }
-:global(:root[data-theme="dark"]) .payment-date {
- color: var(--nord4);
-}
-:global(:root[data-theme="dark"]) .payment-description {
- color: var(--nord5);
-}
-
@media (max-width: 600px) {
.cospend-main {
padding: 0.75rem;
@@ -814,7 +641,7 @@
}
.recent-activity {
- padding: 0.75rem;
+ padding: 0.75rem 0;
}
.actions {
@@ -918,25 +745,10 @@
}
.chart-section .loading {
- background: var(--nord6);
+ background: var(--color-bg-secondary);
border-radius: 0.75rem;
padding: 2rem;
- box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
- border: 1px solid var(--nord4);
text-align: center;
- color: var(--nord2);
+ color: var(--color-text-secondary);
}
-
- @media (prefers-color-scheme: dark) {
- :global(:root:not([data-theme="light"])) .chart-section .loading {
- background: var(--nord1);
- border-color: var(--nord2);
- color: var(--nord4);
- }
- }
-:global(:root[data-theme="dark"]) .chart-section .loading {
- background: var(--nord1);
- border-color: var(--nord2);
- color: var(--nord4);
-}
diff --git a/src/routes/cospend/payments/+page.svelte b/src/routes/cospend/payments/+page.svelte
index b8ca023..d12cc1e 100644
--- a/src/routes/cospend/payments/+page.svelte
+++ b/src/routes/cospend/payments/+page.svelte
@@ -289,23 +289,13 @@
padding: 1rem;
}
-
h1 {
margin-block: 0 1rem;
margin-inline: auto;
- color: var(--nord0);
+ color: var(--color-text-primary);
text-align: center;
}
- @media (prefers-color-scheme: dark) {
- :global(:root:not([data-theme="light"])) h1 {
- color: var(--font-default-dark);
- }
- }
-:global(:root[data-theme="dark"]) h1 {
- color: var(--font-default-dark);
-}
-
.btn {
padding: 0.75rem 1.5rem;
border-radius: 0.5rem;
@@ -328,35 +318,15 @@
}
.btn-secondary {
- background-color: var(--nord5);
- color: var(--nord0);
- border: 1px solid var(--nord4);
+ background-color: var(--color-bg-tertiary);
+ color: var(--color-text-primary);
+ border: 1px solid var(--color-border);
}
.btn-secondary:hover {
- background-color: var(--nord4);
+ background-color: var(--color-bg-elevated);
}
- @media (prefers-color-scheme: dark) {
- :global(:root:not([data-theme="light"])) .btn-secondary {
- background-color: var(--nord2);
- color: var(--font-default-dark);
- border-color: var(--nord3);
- }
-
- :global(:root:not([data-theme="light"])) .btn-secondary:hover {
- background-color: var(--nord3);
- }
- }
-:global(:root[data-theme="dark"]) .btn-secondary {
- background-color: var(--nord2);
- color: var(--font-default-dark);
- border-color: var(--nord3);
-}
-:global(:root[data-theme="dark"]) .btn-secondary:hover {
- background-color: var(--nord3);
-}
-
.loading, .error {
text-align: center;
padding: 2rem;
@@ -365,63 +335,31 @@
.error {
color: var(--red);
- background-color: var(--nord6);
+ background-color: var(--color-bg-secondary);
border-radius: 0.5rem;
border: 1px solid var(--red);
}
- @media (prefers-color-scheme: dark) {
- :global(:root:not([data-theme="light"])) .error {
- background-color: var(--accent-dark);
- }
- }
-:global(:root[data-theme="dark"]) .error {
- background-color: var(--accent-dark);
-}
-
.empty-state {
text-align: center;
padding: 4rem 2rem;
}
.empty-content svg {
- color: var(--nord3);
+ color: var(--color-text-secondary);
margin-bottom: 1rem;
}
.empty-content h2 {
margin: 0 0 0.5rem 0;
- color: var(--nord1);
+ color: var(--color-text-primary);
}
.empty-content p {
margin: 0 0 2rem 0;
- color: var(--nord2);
+ color: var(--color-text-secondary);
}
- @media (prefers-color-scheme: dark) {
- :global(:root:not([data-theme="light"])) .empty-content svg {
- color: var(--nord4);
- }
-
- :global(:root:not([data-theme="light"])) .empty-content h2 {
- color: var(--nord5);
- }
-
- :global(:root:not([data-theme="light"])) .empty-content p {
- color: var(--nord4);
- }
- }
-:global(:root[data-theme="dark"]) .empty-content svg {
- color: var(--nord4);
-}
-:global(:root[data-theme="dark"]) .empty-content h2 {
- color: var(--nord5);
-}
-:global(:root[data-theme="dark"]) .empty-content p {
- color: var(--nord4);
-}
-
.payments-grid {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
@@ -431,14 +369,14 @@
.payment-card {
display: block;
- background: var(--nord6);
+ background: var(--color-surface);
border-radius: 0.75rem;
padding: 1.5rem;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
transition: all 0.2s;
text-decoration: none;
color: inherit;
- border: 1px solid var(--nord4);
+ border: 1px solid var(--color-border);
}
.payment-card:hover {
@@ -446,27 +384,8 @@
text-decoration: none;
color: inherit;
transform: translateY(-1px);
- border-color: var(--nord3);
}
- @media (prefers-color-scheme: dark) {
- :global(:root:not([data-theme="light"])) .payment-card {
- background: var(--nord1);
- border-color: var(--nord2);
- }
-
- :global(:root:not([data-theme="light"])) .payment-card:hover {
- border-color: var(--nord3);
- }
- }
-:global(:root[data-theme="dark"]) .payment-card {
- background: var(--nord1);
- border-color: var(--nord2);
-}
-:global(:root[data-theme="dark"]) .payment-card:hover {
- border-color: var(--nord3);
-}
-
/* Settlement Card Styles */
.settlement-card {
background: linear-gradient(135deg, #e8f5e9, #f1f8e9);
@@ -494,17 +413,10 @@
:global(:root:not([data-theme="light"])) .settlement-card {
background: linear-gradient(135deg, #1a2e1a, #1e2b1e);
}
-
- :global(:root:not([data-theme="light"])) .settlement-card:hover {
- box-shadow: 0 6px 20px rgba(163, 190, 140, 0.3);
- }
}
-:global(:root[data-theme="dark"]) .settlement-card {
- background: linear-gradient(135deg, #1a2e1a, #1e2b1e);
-}
-:global(:root[data-theme="dark"]) .settlement-card:hover {
- box-shadow: 0 6px 20px rgba(163, 190, 140, 0.3);
-}
+ :global(:root[data-theme="dark"]) .settlement-card {
+ background: linear-gradient(135deg, #1a2e1a, #1e2b1e);
+ }
.settlement-header {
display: flex;
@@ -531,20 +443,11 @@
}
.settlement-date {
- color: var(--nord3);
+ color: var(--color-text-secondary);
font-size: 0.9rem;
font-weight: 500;
}
- @media (prefers-color-scheme: dark) {
- :global(:root:not([data-theme="light"])) .settlement-date {
- color: var(--nord4);
- }
- }
-:global(:root[data-theme="dark"]) .settlement-date {
- color: var(--nord4);
-}
-
.settlement-flow {
display: flex;
align-items: center;
@@ -594,25 +497,14 @@
}
.settlement-description {
- color: var(--nord2);
+ color: var(--color-text-tertiary);
margin-top: 1rem;
padding-top: 1rem;
- border-top: 1px solid var(--nord4);
+ border-top: 1px solid var(--color-border);
font-style: italic;
font-size: 0.9rem;
}
- @media (prefers-color-scheme: dark) {
- :global(:root:not([data-theme="light"])) .settlement-description {
- color: var(--nord5);
- border-top-color: var(--nord3);
- }
- }
-:global(:root[data-theme="dark"]) .settlement-description {
- color: var(--nord5);
- border-top-color: var(--nord3);
-}
-
.payment-header {
display: flex;
justify-content: space-between;
@@ -641,29 +533,20 @@
.payment-title h3 {
margin: 0;
- color: var(--nord0);
+ color: var(--color-text-primary);
font-size: 1.25rem;
}
- @media (prefers-color-scheme: dark) {
- :global(:root:not([data-theme="light"])) .payment-title h3 {
- color: var(--font-default-dark);
- }
- }
-:global(:root[data-theme="dark"]) .payment-title h3 {
- color: var(--font-default-dark);
-}
-
.payment-meta {
display: flex;
gap: 1rem;
font-size: 0.9rem;
- color: var(--nord3);
+ color: var(--color-text-secondary);
flex-wrap: wrap;
}
.payment-meta .category-name {
- color: var(--nord3);
+ color: var(--color-text-secondary);
font-style: italic;
font-size: 0.8rem;
}
@@ -673,54 +556,20 @@
color: var(--blue);
}
- @media (prefers-color-scheme: dark) {
- :global(:root:not([data-theme="light"])) .payment-meta {
- color: var(--nord4);
- }
-
- :global(:root:not([data-theme="light"])) .payment-meta .category-name {
- color: var(--nord4);
- }
- }
-:global(:root[data-theme="dark"]) .payment-meta {
- color: var(--nord4);
-}
-:global(:root[data-theme="dark"]) .payment-meta .category-name {
- color: var(--nord4);
-}
-
.receipt-thumb {
width: 60px;
height: 60px;
object-fit: cover;
border-radius: 0.5rem;
- border: 1px solid var(--nord4);
+ border: 1px solid var(--color-border);
}
- @media (prefers-color-scheme: dark) {
- :global(:root:not([data-theme="light"])) .receipt-thumb {
- border-color: var(--nord2);
- }
- }
-:global(:root[data-theme="dark"]) .receipt-thumb {
- border-color: var(--nord2);
-}
-
.payment-description {
- color: var(--nord2);
+ color: var(--color-text-tertiary);
margin-bottom: 1rem;
font-style: italic;
}
- @media (prefers-color-scheme: dark) {
- :global(:root:not([data-theme="light"])) .payment-description {
- color: var(--nord5);
- }
- }
-:global(:root[data-theme="dark"]) .payment-description {
- color: var(--nord5);
-}
-
.payment-details {
margin-bottom: 1rem;
}
@@ -732,58 +581,26 @@
}
.detail-row .label {
- color: var(--nord3);
+ color: var(--color-text-secondary);
font-weight: 500;
}
.detail-row .value {
- color: var(--nord0);
+ color: var(--color-text-primary);
}
- @media (prefers-color-scheme: dark) {
- :global(:root:not([data-theme="light"])) .detail-row .label {
- color: var(--nord4);
- }
-
- :global(:root:not([data-theme="light"])) .detail-row .value {
- color: var(--font-default-dark);
- }
- }
-:global(:root[data-theme="dark"]) .detail-row .label {
- color: var(--nord4);
-}
-:global(:root[data-theme="dark"]) .detail-row .value {
- color: var(--font-default-dark);
-}
-
.splits-summary {
- border-top: 1px solid var(--nord4);
+ border-top: 1px solid var(--color-border);
padding-top: 1rem;
margin-bottom: 1rem;
}
.splits-summary h4 {
margin: 0 0 0.75rem 0;
- color: var(--nord0);
+ color: var(--color-text-primary);
font-size: 1rem;
}
- @media (prefers-color-scheme: dark) {
- :global(:root:not([data-theme="light"])) .splits-summary {
- border-top-color: var(--nord2);
- }
-
- :global(:root:not([data-theme="light"])) .splits-summary h4 {
- color: var(--font-default-dark);
- }
- }
-:global(:root[data-theme="dark"]) .splits-summary {
- border-top-color: var(--nord2);
-}
-:global(:root[data-theme="dark"]) .splits-summary h4 {
- color: var(--font-default-dark);
-}
-
.splits-list {
display: flex;
flex-direction: column;
@@ -797,7 +614,7 @@
}
.split-user {
- color: var(--nord2);
+ color: var(--color-text-tertiary);
}
.split-amount.positive {
@@ -810,16 +627,6 @@
font-weight: 500;
}
- @media (prefers-color-scheme: dark) {
- :global(:root:not([data-theme="light"])) .split-user {
- color: var(--nord5);
- }
- }
-:global(:root[data-theme="dark"]) .split-user {
- color: var(--nord5);
-}
-
-
.pagination {
display: flex;
justify-content: center;
diff --git a/src/routes/cospend/payments/add/+page.svelte b/src/routes/cospend/payments/add/+page.svelte
index 516e587..04c73c5 100644
--- a/src/routes/cospend/payments/add/+page.svelte
+++ b/src/routes/cospend/payments/add/+page.svelte
@@ -9,6 +9,8 @@
import SplitMethodSelector from '$lib/components/cospend/SplitMethodSelector.svelte';
import UsersList from '$lib/components/cospend/UsersList.svelte';
import ImageUpload from '$lib/components/ImageUpload.svelte';
+ import SaveFab from '$lib/components/SaveFab.svelte';
+ import Toggle from '$lib/components/Toggle.svelte';
let { data, form } = $props();
@@ -465,13 +467,9 @@
-
- Make this a recurring payment
+
+ Make this a recurring payment
+
@@ -612,14 +610,7 @@
{error}
{/if}
-
+
@@ -637,32 +628,16 @@
.header h1 {
margin: 0 0 0.5rem 0;
- color: var(--nord0);
+ color: var(--color-text-primary);
font-size: 2rem;
}
.header p {
margin: 0;
- color: var(--nord3);
+ color: var(--color-text-secondary);
font-size: 1.1rem;
}
- @media (prefers-color-scheme: dark) {
- :global(:root:not([data-theme="light"])) .header h1 {
- color: var(--font-default-dark);
- }
-
- :global(:root:not([data-theme="light"])) .header p {
- color: var(--nord4);
- }
- }
-:global(:root[data-theme="dark"]) .header h1 {
- color: var(--font-default-dark);
-}
-:global(:root[data-theme="dark"]) .header p {
- color: var(--nord4);
-}
-
.payment-form {
display: flex;
flex-direction: column;
@@ -670,38 +645,20 @@
}
.form-section {
- background: var(--nord6);
+ background: var(--color-surface);
padding: 1.5rem;
border-radius: 0.75rem;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
- border: 1px solid var(--nord4);
+ border: 1px solid var(--color-border);
}
.form-section h2 {
margin-top: 0;
margin-bottom: 1rem;
- color: var(--nord0);
+ color: var(--color-text-primary);
font-size: 1.25rem;
}
- @media (prefers-color-scheme: dark) {
- :global(:root:not([data-theme="light"])) .form-section {
- background: var(--nord1);
- border-color: var(--nord2);
- }
-
- :global(:root:not([data-theme="light"])) .form-section h2 {
- color: var(--font-default-dark);
- }
- }
-:global(:root[data-theme="dark"]) .form-section {
- background: var(--nord1);
- border-color: var(--nord2);
-}
-:global(:root[data-theme="dark"]) .form-section h2 {
- color: var(--font-default-dark);
-}
-
.form-group {
margin-bottom: 1rem;
}
@@ -716,27 +673,18 @@
display: block;
margin-bottom: 0.5rem;
font-weight: 500;
- color: var(--nord2);
+ color: var(--color-text-secondary);
}
- @media (prefers-color-scheme: dark) {
- :global(:root:not([data-theme="light"])) label {
- color: var(--nord5);
- }
- }
-:global(:root[data-theme="dark"]) label {
- color: var(--nord5);
-}
-
input, textarea, select {
width: 100%;
padding: 0.75rem;
- border: 1px solid var(--nord4);
+ border: 1px solid var(--color-border);
border-radius: 0.5rem;
font-size: 1rem;
box-sizing: border-box;
- background-color: var(--nord6);
- color: var(--nord0);
+ background-color: var(--color-bg-tertiary);
+ color: var(--color-text-primary);
}
input:focus, textarea:focus, select:focus {
@@ -745,29 +693,12 @@
box-shadow: 0 0 0 2px rgba(94, 129, 172, 0.2);
}
- @media (prefers-color-scheme: dark) {
- :global(:root:not([data-theme="light"])) input,
-:global(:root:not([data-theme="light"])) textarea,
-:global(:root:not([data-theme="light"])) select {
- background-color: var(--nord2);
- color: var(--font-default-dark);
- border-color: var(--nord3);
- }
- }
-:global(:root[data-theme="dark"]) input,
-:global(:root[data-theme="dark"]) textarea,
-:global(:root[data-theme="dark"]) select {
- background-color: var(--nord2);
- color: var(--font-default-dark);
- border-color: var(--nord3);
-}
-
.error {
- background-color: var(--nord6);
+ background-color: var(--color-bg-secondary);
color: var(--red);
padding: 1rem;
border-radius: 0.5rem;
@@ -775,81 +706,6 @@
border: 1px solid var(--red);
}
- @media (prefers-color-scheme: dark) {
- :global(:root:not([data-theme="light"])) .error {
- background-color: var(--accent-dark);
- }
- }
-:global(:root[data-theme="dark"]) .error {
- background-color: var(--accent-dark);
-}
-
- .form-actions {
- display: flex;
- gap: 1rem;
- justify-content: flex-end;
- }
-
- .btn-primary, .btn-secondary {
- padding: 0.75rem 1.5rem;
- border-radius: 0.5rem;
- font-size: 1rem;
- cursor: pointer;
- transition: all 0.2s;
- }
-
- .btn-primary {
- background-color: var(--blue);
- color: white;
- border: none;
- }
-
- .btn-primary:hover:not(:disabled) {
- background-color: var(--nord10);
- transform: translateY(-1px);
- box-shadow: 0 4px 8px rgba(0, 0, 0, 0.15);
- }
-
- .btn-primary:disabled {
- opacity: 0.6;
- cursor: not-allowed;
- }
-
- .btn-secondary {
- background-color: var(--nord5);
- color: var(--nord0);
- border: 1px solid var(--nord4);
- text-decoration: none;
- display: inline-block;
- text-align: center;
- }
-
- .btn-secondary:hover {
- background-color: var(--nord4);
- text-decoration: none;
- }
-
- @media (prefers-color-scheme: dark) {
- :global(:root:not([data-theme="light"])) .btn-secondary {
- background-color: var(--nord2);
- color: var(--font-default-dark);
- border-color: var(--nord3);
- }
-
- :global(:root:not([data-theme="light"])) .btn-secondary:hover {
- background-color: var(--nord3);
- }
- }
-:global(:root[data-theme="dark"]) .btn-secondary {
- background-color: var(--nord2);
- color: var(--font-default-dark);
- border-color: var(--nord3);
-}
-:global(:root[data-theme="dark"]) .btn-secondary:hover {
- background-color: var(--nord3);
-}
-
-
/* Progressive enhancement styles */
.no-js-only {
display: block;
@@ -862,7 +718,7 @@
.manual-users textarea {
width: 100%;
padding: 0.75rem;
- border: 1px solid #ddd;
+ border: 1px solid var(--color-border);
border-radius: 0.5rem;
font-family: inherit;
font-size: 0.9rem;
@@ -872,91 +728,46 @@
.manual-users p {
margin: 0 0 0.5rem 0;
font-size: 0.9rem;
- color: var(--nord2);
+ color: var(--color-text-secondary);
}
- @media (prefers-color-scheme: dark) {
- :global(:root:not([data-theme="light"])) .manual-users p {
- color: var(--nord4);
- }
- }
-:global(:root[data-theme="dark"]) .manual-users p {
- color: var(--nord4);
-}
-
/* Recurring payment styles */
.checkbox-label {
display: flex !important;
align-items: center;
- gap: 0.5rem;
+ gap: 0.75rem;
cursor: pointer;
}
- .checkbox-label input[type="checkbox"] {
- width: auto;
- margin: 0;
- }
-
.recurring-options {
margin-top: 1rem;
padding: 1rem;
- background-color: var(--nord5);
+ background-color: var(--color-bg-tertiary);
border-radius: 0.5rem;
- border: 1px solid var(--nord4);
+ border: 1px solid var(--color-border);
}
- @media (prefers-color-scheme: dark) {
- :global(:root:not([data-theme="light"])) .recurring-options {
- background-color: var(--nord2);
- border-color: var(--nord3);
- }
- }
-:global(:root[data-theme="dark"]) .recurring-options {
- background-color: var(--nord2);
- border-color: var(--nord3);
-}
-
.help-text {
display: block;
margin-top: 0.25rem;
font-size: 0.8rem;
- color: var(--nord3);
+ color: var(--color-text-secondary);
font-style: italic;
}
- @media (prefers-color-scheme: dark) {
- :global(:root:not([data-theme="light"])) .help-text {
- color: var(--nord4);
- }
- }
-:global(:root[data-theme="dark"]) .help-text {
- color: var(--nord4);
-}
-
.help-text p {
margin: 0.5rem 0 0.25rem 0;
}
.help-text code {
- background-color: var(--nord5);
+ background-color: var(--color-bg-tertiary);
padding: 0.125rem 0.25rem;
border-radius: 0.25rem;
font-family: monospace;
font-size: 0.85em;
- border: 1px solid var(--nord4);
+ border: 1px solid var(--color-border);
}
- @media (prefers-color-scheme: dark) {
- :global(:root:not([data-theme="light"])) .help-text code {
- background-color: var(--nord2);
- border-color: var(--nord3);
- }
- }
-:global(:root[data-theme="dark"]) .help-text code {
- background-color: var(--nord2);
- border-color: var(--nord3);
-}
-
.help-text ul {
margin: 0.5rem 0;
padding-left: 1rem;
@@ -979,7 +790,7 @@
}
.execution-preview {
- background-color: var(--nord8);
+ background-color: var(--color-bg-tertiary);
border: 1px solid var(--blue);
border-radius: 0.5rem;
padding: 1rem;
@@ -1000,28 +811,12 @@
}
.frequency-description {
- color: var(--nord2);
+ color: var(--color-text-secondary);
font-size: 0.9rem;
margin: 0;
font-style: italic;
}
- @media (prefers-color-scheme: dark) {
- :global(:root:not([data-theme="light"])) .execution-preview {
- background-color: var(--nord2);
- }
-
- :global(:root:not([data-theme="light"])) .frequency-description {
- color: var(--nord4);
- }
- }
-:global(:root[data-theme="dark"]) .execution-preview {
- background-color: var(--nord2);
-}
-:global(:root[data-theme="dark"]) .frequency-description {
- color: var(--nord4);
-}
-
/* Amount-currency styling */
.amount-currency {
display: flex;
@@ -1050,21 +845,21 @@
}
.conversion-preview.loading {
- background-color: var(--nord8);
+ background-color: var(--color-bg-tertiary);
border-color: var(--blue);
color: var(--blue);
}
.conversion-preview.error {
- background-color: var(--nord6);
+ background-color: var(--color-bg-secondary);
border-color: var(--red);
color: var(--red);
}
.conversion-preview.success {
- background-color: var(--nord14);
+ background-color: var(--color-bg-tertiary);
border-color: var(--green);
- color: var(--nord0);
+ color: var(--color-text-primary);
}
.conversion-preview small {
@@ -1072,31 +867,6 @@
font-weight: 500;
}
- @media (prefers-color-scheme: dark) {
- :global(:root:not([data-theme="light"])) .conversion-preview.loading {
- background-color: var(--nord2);
- }
-
- :global(:root:not([data-theme="light"])) .conversion-preview.error {
- background-color: var(--accent-dark);
- }
-
- :global(:root:not([data-theme="light"])) .conversion-preview.success {
- background-color: var(--nord2);
- color: var(--font-default-dark);
- }
- }
-:global(:root[data-theme="dark"]) .conversion-preview.loading {
- background-color: var(--nord2);
-}
-:global(:root[data-theme="dark"]) .conversion-preview.error {
- background-color: var(--accent-dark);
-}
-:global(:root[data-theme="dark"]) .conversion-preview.success {
- background-color: var(--nord2);
- color: var(--font-default-dark);
-}
-
@media (max-width: 600px) {
.add-payment {
padding: 1rem;
@@ -1106,10 +876,6 @@
grid-template-columns: 1fr;
}
- .form-actions {
- flex-direction: column;
- }
-
.amount-currency {
flex-direction: column;
}
@@ -1119,4 +885,5 @@
flex: none;
}
}
+
\ No newline at end of file
diff --git a/src/routes/cospend/payments/edit/[id]/+page.svelte b/src/routes/cospend/payments/edit/[id]/+page.svelte
index bd884cb..aad8762 100644
--- a/src/routes/cospend/payments/edit/[id]/+page.svelte
+++ b/src/routes/cospend/payments/edit/[id]/+page.svelte
@@ -4,6 +4,7 @@
import { getCategoryOptions } from '$lib/utils/categories';
import FormSection from '$lib/components/FormSection.svelte';
import ImageUpload from '$lib/components/ImageUpload.svelte';
+ import SaveFab from '$lib/components/SaveFab.svelte';
/**
* @typedef {import('$models/Payment').IPayment & {splits?: import('$models/PaymentSplit').IPaymentSplit[]}} PaymentWithSplits
@@ -582,15 +583,9 @@
>
{deleting ? 'Deleting...' : 'Delete Payment'}
-
- goto('/cospend/payments')}>
- Cancel
-
-
- {saving ? 'Saving...' : 'Save Changes'}
-
-
+
+
{/if}
@@ -609,32 +604,16 @@
.header h1 {
margin: 0 0 0.5rem 0;
- color: var(--nord0);
+ color: var(--color-text-primary);
font-size: 2rem;
}
.header p {
margin: 0;
- color: var(--nord3);
+ color: var(--color-text-secondary);
font-size: 1.1rem;
}
- @media (prefers-color-scheme: dark) {
- :global(:root:not([data-theme="light"])) .header h1 {
- color: var(--font-default-dark);
- }
-
- :global(:root:not([data-theme="light"])) .header p {
- color: var(--nord4);
- }
- }
-:global(:root[data-theme="dark"]) .header h1 {
- color: var(--font-default-dark);
-}
-:global(:root[data-theme="dark"]) .header p {
- color: var(--nord4);
-}
-
.loading, .error {
text-align: center;
padding: 2rem;
@@ -643,20 +622,11 @@
.error {
color: var(--red);
- background-color: var(--nord6);
+ background-color: var(--color-bg-secondary);
border-radius: 0.5rem;
border: 1px solid var(--red);
}
- @media (prefers-color-scheme: dark) {
- :global(:root:not([data-theme="light"])) .error {
- background-color: var(--accent-dark);
- }
- }
-:global(:root[data-theme="dark"]) .error {
- background-color: var(--accent-dark);
-}
-
.payment-form {
display: flex;
flex-direction: column;
@@ -677,27 +647,18 @@
display: block;
margin-bottom: 0.5rem;
font-weight: 500;
- color: var(--nord2);
+ color: var(--color-text-secondary);
}
- @media (prefers-color-scheme: dark) {
- :global(:root:not([data-theme="light"])) label {
- color: var(--nord5);
- }
- }
-:global(:root[data-theme="dark"]) label {
- color: var(--nord5);
-}
-
input, textarea, select {
width: 100%;
padding: 0.75rem;
- border: 1px solid var(--nord4);
+ border: 1px solid var(--color-border);
border-radius: 0.5rem;
font-size: 1rem;
box-sizing: border-box;
- background-color: var(--nord6);
- color: var(--nord0);
+ background-color: var(--color-bg-tertiary);
+ color: var(--color-text-primary);
}
input:focus, textarea:focus, select:focus {
@@ -710,48 +671,20 @@
cursor: pointer;
}
- @media (prefers-color-scheme: dark) {
- :global(:root:not([data-theme="light"])) input,
-:global(:root:not([data-theme="light"])) textarea,
-:global(:root:not([data-theme="light"])) select {
- background-color: var(--nord2);
- color: var(--font-default-dark);
- border-color: var(--nord3);
- }
- }
-:global(:root[data-theme="dark"]) input,
-:global(:root[data-theme="dark"]) textarea,
-:global(:root[data-theme="dark"]) select {
- background-color: var(--nord2);
- color: var(--font-default-dark);
- border-color: var(--nord3);
-}
-
.split-method-info {
display: flex;
align-items: center;
gap: 0.5rem;
margin-bottom: 1rem;
padding: 0.75rem;
- background-color: var(--nord14);
+ background-color: var(--color-bg-tertiary);
border-radius: 0.5rem;
border: 1px solid var(--green);
}
- @media (prefers-color-scheme: dark) {
- :global(:root:not([data-theme="light"])) .split-method-info {
- background-color: var(--nord2);
- border-color: var(--nord3);
- }
- }
-:global(:root[data-theme="dark"]) .split-method-info {
- background-color: var(--nord2);
- border-color: var(--nord3);
-}
-
.split-method-info .label {
font-weight: 600;
- color: var(--nord1);
+ color: var(--color-text-secondary);
}
.split-method-info .value {
@@ -759,66 +692,28 @@
font-weight: 500;
}
- @media (prefers-color-scheme: dark) {
- :global(:root:not([data-theme="light"])) .split-method-info .label {
- color: var(--nord5);
- }
- }
-:global(:root[data-theme="dark"]) .split-method-info .label {
- color: var(--nord5);
-}
-
.personal-amounts-editor {
margin-bottom: 1.5rem;
padding: 1rem;
- background-color: var(--nord5);
+ background-color: var(--color-bg-tertiary);
border-radius: 0.5rem;
- border: 1px solid var(--nord4);
+ border: 1px solid var(--color-border);
}
- @media (prefers-color-scheme: dark) {
- :global(:root:not([data-theme="light"])) .personal-amounts-editor {
- background-color: var(--nord2);
- border-color: var(--nord3);
- }
- }
-:global(:root[data-theme="dark"]) .personal-amounts-editor {
- background-color: var(--nord2);
- border-color: var(--nord3);
-}
-
.personal-amounts-editor h3 {
margin-top: 0;
margin-bottom: 0.5rem;
- color: var(--nord0);
+ color: var(--color-text-primary);
font-size: 1rem;
}
- @media (prefers-color-scheme: dark) {
- :global(:root:not([data-theme="light"])) .personal-amounts-editor h3 {
- color: var(--font-default-dark);
- }
- }
-:global(:root[data-theme="dark"]) .personal-amounts-editor h3 {
- color: var(--font-default-dark);
-}
-
.personal-amounts-editor .description {
- color: var(--nord2);
+ color: var(--color-text-secondary);
font-size: 0.9rem;
margin-bottom: 1rem;
font-style: italic;
}
- @media (prefers-color-scheme: dark) {
- :global(:root:not([data-theme="light"])) .personal-amounts-editor .description {
- color: var(--nord4);
- }
- }
-:global(:root[data-theme="dark"]) .personal-amounts-editor .description {
- color: var(--nord4);
-}
-
.personal-input {
display: flex;
align-items: center;
@@ -835,11 +730,11 @@
.personal-input input {
max-width: 150px;
padding: 0.5rem;
- border: 1px solid var(--nord4);
+ border: 1px solid var(--color-border);
border-radius: 0.5rem;
font-size: 1rem;
- background-color: var(--nord6);
- color: var(--nord0);
+ background-color: var(--color-bg-tertiary);
+ color: var(--color-text-primary);
}
.personal-input input:focus {
@@ -848,68 +743,26 @@
box-shadow: 0 0 0 2px rgba(94, 129, 172, 0.2);
}
- @media (prefers-color-scheme: dark) {
- :global(:root:not([data-theme="light"])) .personal-input input {
- background-color: var(--nord1);
- color: var(--font-default-dark);
- border-color: var(--nord3);
- }
- }
-:global(:root[data-theme="dark"]) .personal-input input {
- background-color: var(--nord1);
- color: var(--font-default-dark);
- border-color: var(--nord3);
-}
-
.remainder-info {
margin-top: 1rem;
padding: 0.75rem;
- background-color: var(--nord14);
+ background-color: var(--color-bg-tertiary);
border-radius: 0.5rem;
border: 1px solid var(--green);
}
.remainder-info.error {
- background-color: var(--nord6);
+ background-color: var(--color-bg-secondary);
border-color: var(--red);
}
- @media (prefers-color-scheme: dark) {
- :global(:root:not([data-theme="light"])) .remainder-info {
- background-color: var(--nord1);
- border-color: var(--nord3);
- }
-
- :global(:root:not([data-theme="light"])) .remainder-info.error {
- background-color: var(--accent-dark);
- border-color: var(--red);
- }
- }
-:global(:root[data-theme="dark"]) .remainder-info {
- background-color: var(--nord1);
- border-color: var(--nord3);
-}
-:global(:root[data-theme="dark"]) .remainder-info.error {
- background-color: var(--accent-dark);
- border-color: var(--red);
-}
-
.remainder-info span {
display: block;
margin-bottom: 0.5rem;
font-weight: 500;
- color: var(--nord0);
+ color: var(--color-text-primary);
}
- @media (prefers-color-scheme: dark) {
- :global(:root:not([data-theme="light"])) .remainder-info span {
- color: var(--font-default-dark);
- }
- }
-:global(:root[data-theme="dark"]) .remainder-info span {
- color: var(--font-default-dark);
-}
-
.error-message {
color: var(--red);
font-weight: 600;
@@ -927,54 +780,25 @@
.splits-display h3 {
margin-top: 0;
margin-bottom: 1rem;
- color: var(--nord0);
+ color: var(--color-text-primary);
font-size: 1rem;
}
- @media (prefers-color-scheme: dark) {
- :global(:root:not([data-theme="light"])) .splits-display h3 {
- color: var(--font-default-dark);
- }
- }
-:global(:root[data-theme="dark"]) .splits-display h3 {
- color: var(--font-default-dark);
-}
-
.split-item {
display: flex;
justify-content: space-between;
align-items: center;
padding: 0.75rem;
- background-color: var(--nord5);
+ background-color: var(--color-bg-tertiary);
border-radius: 0.5rem;
- border: 1px solid var(--nord4);
+ border: 1px solid var(--color-border);
}
- @media (prefers-color-scheme: dark) {
- :global(:root:not([data-theme="light"])) .split-item {
- background-color: var(--nord2);
- border-color: var(--nord3);
- }
- }
-:global(:root[data-theme="dark"]) .split-item {
- background-color: var(--nord2);
- border-color: var(--nord3);
-}
-
.split-username {
font-weight: 500;
- color: var(--nord0);
+ color: var(--color-text-primary);
}
- @media (prefers-color-scheme: dark) {
- :global(:root:not([data-theme="light"])) .split-username {
- color: var(--font-default-dark);
- }
- }
-:global(:root[data-theme="dark"]) .split-username {
- color: var(--font-default-dark);
-}
-
.split-amount.positive {
color: var(--green);
font-weight: 500;
@@ -986,21 +810,12 @@
}
.note {
- color: var(--nord2);
+ color: var(--color-text-secondary);
font-size: 0.9rem;
font-style: italic;
margin: 0;
}
- @media (prefers-color-scheme: dark) {
- :global(:root:not([data-theme="light"])) .note {
- color: var(--nord4);
- }
- }
-:global(:root[data-theme="dark"]) .note {
- color: var(--nord4);
-}
-
.js-only {
display: none;
}
@@ -1024,68 +839,12 @@
gap: 1rem;
}
- .main-actions {
- display: flex;
- gap: 1rem;
- }
-
- .btn-primary, .btn-secondary, .btn-danger {
+ .btn-danger {
padding: 0.75rem 1.5rem;
border-radius: 0.5rem;
font-size: 1rem;
cursor: pointer;
transition: all 0.2s;
- }
-
- .btn-primary {
- background-color: var(--blue);
- color: white;
- border: none;
- }
-
- .btn-primary:hover:not(:disabled) {
- background-color: var(--nord10);
- transform: translateY(-1px);
- box-shadow: 0 4px 8px rgba(0, 0, 0, 0.15);
- }
-
- .btn-primary:disabled {
- opacity: 0.6;
- cursor: not-allowed;
- }
-
- .btn-secondary {
- background-color: var(--nord5);
- color: var(--nord0);
- border: 1px solid var(--nord4);
- }
-
- .btn-secondary:hover {
- background-color: var(--nord4);
- transform: translateY(-1px);
- }
-
- @media (prefers-color-scheme: dark) {
- :global(:root:not([data-theme="light"])) .btn-secondary {
- background-color: var(--nord2);
- color: var(--font-default-dark);
- border-color: var(--nord3);
- }
-
- :global(:root:not([data-theme="light"])) .btn-secondary:hover {
- background-color: var(--nord3);
- }
- }
-:global(:root[data-theme="dark"]) .btn-secondary {
- background-color: var(--nord2);
- color: var(--font-default-dark);
- border-color: var(--nord3);
-}
-:global(:root[data-theme="dark"]) .btn-secondary:hover {
- background-color: var(--nord3);
-}
-
- .btn-danger {
background-color: var(--red);
color: white;
border: none;
@@ -1129,21 +888,21 @@
}
.conversion-preview.loading {
- background-color: var(--nord8);
+ background-color: var(--color-bg-tertiary);
border-color: var(--blue);
color: var(--blue);
}
.conversion-preview.error {
- background-color: var(--nord6);
+ background-color: var(--color-bg-secondary);
border-color: var(--red);
color: var(--red);
}
.conversion-preview.success {
- background-color: var(--nord14);
+ background-color: var(--color-bg-tertiary);
border-color: var(--green);
- color: var(--nord0);
+ color: var(--color-text-primary);
}
.conversion-preview small {
@@ -1155,42 +914,10 @@
display: block;
margin-top: 0.25rem;
font-size: 0.8rem;
- color: var(--nord3);
+ color: var(--color-text-secondary);
font-style: italic;
}
- @media (prefers-color-scheme: dark) {
- :global(:root:not([data-theme="light"])) .conversion-preview.loading {
- background-color: var(--nord2);
- }
-
- :global(:root:not([data-theme="light"])) .conversion-preview.error {
- background-color: var(--accent-dark);
- }
-
- :global(:root:not([data-theme="light"])) .conversion-preview.success {
- background-color: var(--nord2);
- color: var(--font-default-dark);
- }
-
- :global(:root:not([data-theme="light"])) .help-text {
- color: var(--nord4);
- }
- }
-:global(:root[data-theme="dark"]) .conversion-preview.loading {
- background-color: var(--nord2);
-}
-:global(:root[data-theme="dark"]) .conversion-preview.error {
- background-color: var(--accent-dark);
-}
-:global(:root[data-theme="dark"]) .conversion-preview.success {
- background-color: var(--nord2);
- color: var(--font-default-dark);
-}
-:global(:root[data-theme="dark"]) .help-text {
- color: var(--nord4);
-}
-
@media (max-width: 600px) {
.edit-payment {
padding: 1rem;
@@ -1232,4 +959,5 @@
max-width: none;
}
}
+
\ No newline at end of file
diff --git a/src/routes/cospend/payments/view/[id]/+page.svelte b/src/routes/cospend/payments/view/[id]/+page.svelte
index 6beba03..6d672b9 100644
--- a/src/routes/cospend/payments/view/[id]/+page.svelte
+++ b/src/routes/cospend/payments/view/[id]/+page.svelte
@@ -4,7 +4,7 @@
import ProfilePicture from '$lib/components/cospend/ProfilePicture.svelte';
import { getCategoryEmoji, getCategoryName } from '$lib/utils/categories';
import EditButton from '$lib/components/EditButton.svelte';
-
+
import { formatCurrency } from '$lib/utils/formatters';
@@ -21,7 +21,7 @@
onMount(async () => {
// Mark that JavaScript is loaded
document.body.classList.add('js-loaded');
-
+
// Only refresh if we don't have server data
if (!payment) {
await loadPayment();
@@ -48,7 +48,7 @@
if (payment.currency === 'CHF' || !payment.originalAmount) {
return formatCurrency(payment.amount, 'CHF', 'de-CH');
}
-
+
return `${formatCurrency(payment.originalAmount, payment.currency, 'de-CH')} ≈ ${formatCurrency(payment.amount, 'CHF', 'de-CH')}`;
}
@@ -58,7 +58,7 @@
function getSplitDescription(/** @type {any} */ payment) {
if (!payment.splits || payment.splits.length === 0) return 'No splits';
-
+
if (payment.splitMethod === 'equal') {
return `Split equally among ${payment.splits.length} people`;
} else if (payment.splitMethod === 'full') {
@@ -182,8 +182,6 @@
padding: 2rem;
}
-
-
.loading, .error {
text-align: center;
padding: 2rem;
@@ -192,57 +190,27 @@
.error {
color: var(--red);
- background-color: var(--nord6);
+ background-color: var(--color-bg-secondary);
border-radius: 0.5rem;
border: 1px solid var(--red);
}
- @media (prefers-color-scheme: dark) {
- :global(:root:not([data-theme="light"])) .error {
- background-color: var(--accent-dark);
- }
- }
-:global(:root[data-theme="dark"]) .error {
- background-color: var(--accent-dark);
-}
-
.payment-card {
- background: var(--nord6);
+ background: var(--color-surface);
border-radius: 0.75rem;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
overflow: hidden;
- border: 1px solid var(--nord4);
+ border: 1px solid var(--color-border);
}
- @media (prefers-color-scheme: dark) {
- :global(:root:not([data-theme="light"])) .payment-card {
- background: var(--nord1);
- border-color: var(--nord2);
- }
- }
-:global(:root[data-theme="dark"]) .payment-card {
- background: var(--nord1);
- border-color: var(--nord2);
-}
-
.payment-header {
display: flex;
justify-content: space-between;
align-items: flex-start;
padding: 2rem;
- background: linear-gradient(135deg, var(--nord5), var(--nord4));
- border-bottom: 1px solid var(--nord3);
+ background: var(--color-bg-tertiary);
}
- @media (prefers-color-scheme: dark) {
- :global(:root:not([data-theme="light"])) .payment-header {
- background: linear-gradient(135deg, var(--nord2), var(--nord3));
- }
- }
-:global(:root[data-theme="dark"]) .payment-header {
- background: linear-gradient(135deg, var(--nord2), var(--nord3));
-}
-
.title-with-category {
display: flex;
align-items: center;
@@ -257,7 +225,7 @@
.title-section h1 {
margin: 0;
- color: var(--nord0);
+ color: var(--color-text-primary);
font-size: 1.75rem;
}
@@ -267,15 +235,6 @@
color: var(--blue);
}
- @media (prefers-color-scheme: dark) {
- :global(:root:not([data-theme="light"])) .title-section h1 {
- color: var(--font-default-dark);
- }
- }
-:global(:root[data-theme="dark"]) .title-section h1 {
- color: var(--font-default-dark);
-}
-
.receipt-image {
flex-shrink: 0;
margin-left: 2rem;
@@ -286,18 +245,9 @@
max-height: 150px;
object-fit: cover;
border-radius: 0.5rem;
- border: 1px solid var(--nord4);
+ border: 1px solid var(--color-border);
}
- @media (prefers-color-scheme: dark) {
- :global(:root:not([data-theme="light"])) .receipt-image img {
- border-color: var(--nord2);
- }
- }
-:global(:root[data-theme="dark"]) .receipt-image img {
- border-color: var(--nord2);
-}
-
.payment-info {
padding: 2rem;
}
@@ -317,100 +267,43 @@
.label {
font-weight: 600;
- color: var(--nord3);
+ color: var(--color-text-secondary);
font-size: 0.9rem;
text-transform: uppercase;
letter-spacing: 0.5px;
}
.value {
- color: var(--nord0);
+ color: var(--color-text-primary);
font-size: 1rem;
}
- @media (prefers-color-scheme: dark) {
- :global(:root:not([data-theme="light"])) .label {
- color: var(--nord4);
- }
-
- :global(:root:not([data-theme="light"])) .value {
- color: var(--font-default-dark);
- }
- }
-:global(:root[data-theme="dark"]) .label {
- color: var(--nord4);
-}
-:global(:root[data-theme="dark"]) .value {
- color: var(--font-default-dark);
-}
-
.description {
- border-top: 1px solid var(--nord4);
padding-top: 1.5rem;
}
.description h3 {
margin: 0 0 0.75rem 0;
- color: var(--nord0);
+ color: var(--color-text-primary);
font-size: 1.1rem;
}
.description p {
margin: 0;
- color: var(--nord2);
+ color: var(--color-text-tertiary);
line-height: 1.5;
}
- @media (prefers-color-scheme: dark) {
- :global(:root:not([data-theme="light"])) .description {
- border-top-color: var(--nord2);
- }
-
- :global(:root:not([data-theme="light"])) .description h3 {
- color: var(--font-default-dark);
- }
-
- :global(:root:not([data-theme="light"])) .description p {
- color: var(--nord5);
- }
- }
-:global(:root[data-theme="dark"]) .description {
- border-top-color: var(--nord2);
-}
-:global(:root[data-theme="dark"]) .description h3 {
- color: var(--font-default-dark);
-}
-:global(:root[data-theme="dark"]) .description p {
- color: var(--nord5);
-}
-
.splits-section {
- border-top: 1px solid var(--nord4);
padding: 2rem;
}
.splits-section h3 {
margin: 0 0 1rem 0;
- color: var(--nord0);
+ color: var(--color-text-primary);
font-size: 1.1rem;
}
- @media (prefers-color-scheme: dark) {
- :global(:root:not([data-theme="light"])) .splits-section {
- border-top-color: var(--nord2);
- }
-
- :global(:root:not([data-theme="light"])) .splits-section h3 {
- color: var(--font-default-dark);
- }
- }
-:global(:root[data-theme="dark"]) .splits-section {
- border-top-color: var(--nord2);
-}
-:global(:root[data-theme="dark"]) .splits-section h3 {
- color: var(--font-default-dark);
-}
-
.splits-list {
display: flex;
flex-direction: column;
@@ -422,36 +315,14 @@
justify-content: space-between;
align-items: center;
padding: 1rem;
- background: var(--nord5);
+ background: var(--color-bg-primary);
border-radius: 0.5rem;
- border: 1px solid var(--nord4);
}
.split-item.current-user {
- background: var(--nord8);
- border-color: var(--blue);
+ background: var(--color-bg-tertiary);
}
- @media (prefers-color-scheme: dark) {
- :global(:root:not([data-theme="light"])) .split-item {
- background: var(--nord2);
- border-color: var(--nord3);
- }
-
- :global(:root:not([data-theme="light"])) .split-item.current-user {
- background: var(--nord3);
- border-color: var(--blue);
- }
- }
-:global(:root[data-theme="dark"]) .split-item {
- background: var(--nord2);
- border-color: var(--nord3);
-}
-:global(:root[data-theme="dark"]) .split-item.current-user {
- background: var(--nord3);
- border-color: var(--blue);
-}
-
.split-user {
display: flex;
align-items: center;
@@ -466,7 +337,7 @@
.username {
font-weight: 500;
- color: var(--nord0);
+ color: var(--color-text-primary);
}
.you-badge {
@@ -478,15 +349,6 @@
font-weight: 500;
}
- @media (prefers-color-scheme: dark) {
- :global(:root:not([data-theme="light"])) .username {
- color: var(--font-default-dark);
- }
- }
-:global(:root[data-theme="dark"]) .username {
- color: var(--font-default-dark);
-}
-
.split-amount {
font-weight: 500;
font-size: 1rem;
@@ -502,7 +364,7 @@
.exchange-rate-info {
margin-top: 0.5rem;
- color: var(--nord3);
+ color: var(--color-text-secondary);
font-style: italic;
}
@@ -510,15 +372,6 @@
font-size: 0.8rem;
}
- @media (prefers-color-scheme: dark) {
- :global(:root:not([data-theme="light"])) .exchange-rate-info {
- color: var(--nord4);
- }
- }
-:global(:root[data-theme="dark"]) .exchange-rate-info {
- color: var(--nord4);
-}
-
@media (max-width: 600px) {
.payment-view {
padding: 1rem;
@@ -544,4 +397,4 @@
gap: 0.5rem;
}
}
-
\ No newline at end of file
+
diff --git a/src/routes/cospend/recurring/+page.svelte b/src/routes/cospend/recurring/+page.svelte
index 1e8d69a..10c5710 100644
--- a/src/routes/cospend/recurring/+page.svelte
+++ b/src/routes/cospend/recurring/+page.svelte
@@ -6,6 +6,7 @@
import { toast } from '$lib/js/toast.svelte';
import AddButton from '$lib/components/AddButton.svelte';
import { formatCurrency } from '$lib/utils/formatters';
+ import Toggle from '$lib/components/Toggle.svelte';
let { data } = $props();
@@ -102,8 +103,8 @@
-
- Show active only
+
+ Show active only
@@ -143,7 +144,7 @@
Category:
{getCategoryName(payment.category)}
-
+
Frequency:
{getFrequencyDescription(payment)}
@@ -241,68 +242,33 @@
.header h1 {
margin: 0 0 0.5rem 0;
- color: var(--nord0);
+ color: var(--color-text-primary);
font-size: 2rem;
}
.header p {
margin: 0;
- color: var(--nord3);
+ color: var(--color-text-secondary);
font-size: 1.1rem;
}
- @media (prefers-color-scheme: dark) {
- :global(:root:not([data-theme="light"])) .header h1 {
- color: var(--font-default-dark);
- }
-
- :global(:root:not([data-theme="light"])) .header p {
- color: var(--nord4);
- }
- }
-:global(:root[data-theme="dark"]) .header h1 {
- color: var(--font-default-dark);
-}
-:global(:root[data-theme="dark"]) .header p {
- color: var(--nord4);
-}
-
.filters {
margin-bottom: 1.5rem;
padding: 1rem;
- background: var(--nord6);
+ background: var(--color-surface);
border-radius: 0.5rem;
- box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
- border: 1px solid var(--nord4);
+ border: 1px solid var(--color-border);
}
.filters label {
display: flex;
align-items: center;
- gap: 0.5rem;
+ gap: 0.75rem;
cursor: pointer;
font-weight: 500;
- color: var(--nord0);
+ color: var(--color-text-primary);
}
- @media (prefers-color-scheme: dark) {
- :global(:root:not([data-theme="light"])) .filters {
- background: var(--nord1);
- border-color: var(--nord2);
- }
-
- :global(:root:not([data-theme="light"])) .filters label {
- color: var(--font-default-dark);
- }
- }
-:global(:root[data-theme="dark"]) .filters {
- background: var(--nord1);
- border-color: var(--nord2);
-}
-:global(:root[data-theme="dark"]) .filters label {
- color: var(--font-default-dark);
-}
-
.loading, .error {
text-align: center;
padding: 2rem;
@@ -311,67 +277,32 @@
.error {
color: var(--red);
- background-color: var(--nord6);
+ background-color: var(--color-bg-secondary);
border-radius: 0.5rem;
border: 1px solid var(--red);
}
- @media (prefers-color-scheme: dark) {
- :global(:root:not([data-theme="light"])) .error {
- background-color: var(--accent-dark);
- }
- }
-:global(:root[data-theme="dark"]) .error {
- background-color: var(--accent-dark);
-}
-
.empty-state {
text-align: center;
padding: 4rem 2rem;
- background: var(--nord6);
+ background: var(--color-surface);
border-radius: 0.75rem;
- box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
- border: 1px solid var(--nord4);
+ border: 1px solid var(--color-border);
}
.empty-state h2 {
margin-bottom: 1rem;
- color: var(--nord0);
+ color: var(--color-text-primary);
}
.empty-state p {
- color: var(--nord2);
+ color: var(--color-text-secondary);
margin-bottom: 2rem;
max-width: 500px;
margin-left: auto;
margin-right: auto;
}
- @media (prefers-color-scheme: dark) {
- :global(:root:not([data-theme="light"])) .empty-state {
- background: var(--nord1);
- border-color: var(--nord2);
- }
-
- :global(:root:not([data-theme="light"])) .empty-state h2 {
- color: var(--font-default-dark);
- }
-
- :global(:root:not([data-theme="light"])) .empty-state p {
- color: var(--nord4);
- }
- }
-:global(:root[data-theme="dark"]) .empty-state {
- background: var(--nord1);
- border-color: var(--nord2);
-}
-:global(:root[data-theme="dark"]) .empty-state h2 {
- color: var(--font-default-dark);
-}
-:global(:root[data-theme="dark"]) .empty-state p {
- color: var(--nord4);
-}
-
.payments-grid {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(400px, 1fr));
@@ -379,53 +310,24 @@
}
.payment-card {
- background: var(--nord6);
+ background: var(--color-surface);
border-radius: 0.75rem;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
padding: 1.5rem;
transition: all 0.2s;
- border: 1px solid var(--nord4);
+ border: 1px solid var(--color-border);
}
.payment-card:hover {
transform: translateY(-1px);
box-shadow: 0 4px 16px rgba(0, 0, 0, 0.15);
- border-color: var(--nord3);
}
.payment-card.inactive {
opacity: 0.7;
- background: var(--nord5);
- border-color: var(--nord3);
+ background: var(--color-bg-tertiary);
}
- @media (prefers-color-scheme: dark) {
- :global(:root:not([data-theme="light"])) .payment-card {
- background: var(--nord1);
- border-color: var(--nord2);
- }
-
- :global(:root:not([data-theme="light"])) .payment-card:hover {
- border-color: var(--nord3);
- }
-
- :global(:root:not([data-theme="light"])) .payment-card.inactive {
- background: var(--nord2);
- border-color: var(--nord3);
- }
- }
-:global(:root[data-theme="dark"]) .payment-card {
- background: var(--nord1);
- border-color: var(--nord2);
-}
-:global(:root[data-theme="dark"]) .payment-card:hover {
- border-color: var(--nord3);
-}
-:global(:root[data-theme="dark"]) .payment-card.inactive {
- background: var(--nord2);
- border-color: var(--nord3);
-}
-
.card-header {
display: flex;
justify-content: space-between;
@@ -446,19 +348,10 @@
.payment-title h3 {
margin: 0;
- color: var(--nord0);
+ color: var(--color-text-primary);
font-size: 1.25rem;
}
- @media (prefers-color-scheme: dark) {
- :global(:root:not([data-theme="light"])) .payment-title h3 {
- color: var(--font-default-dark);
- }
- }
-:global(:root[data-theme="dark"]) .payment-title h3 {
- color: var(--font-default-dark);
-}
-
.status-badge {
padding: 0.25rem 0.75rem;
border-radius: 1rem;
@@ -485,20 +378,11 @@
}
.payment-description {
- color: var(--nord2);
+ color: var(--color-text-tertiary);
margin-bottom: 1rem;
font-style: italic;
}
- @media (prefers-color-scheme: dark) {
- :global(:root:not([data-theme="light"])) .payment-description {
- color: var(--nord5);
- }
- }
-:global(:root[data-theme="dark"]) .payment-description {
- color: var(--nord5);
-}
-
.payment-details {
margin-bottom: 1.5rem;
}
@@ -513,12 +397,12 @@
.label {
font-weight: 500;
- color: var(--nord3);
+ color: var(--color-text-secondary);
font-size: 0.9rem;
}
.value {
- color: var(--nord0);
+ color: var(--color-text-primary);
font-weight: 500;
}
@@ -527,22 +411,6 @@
font-weight: 600;
}
- @media (prefers-color-scheme: dark) {
- :global(:root:not([data-theme="light"])) .label {
- color: var(--nord4);
- }
-
- :global(:root:not([data-theme="light"])) .value {
- color: var(--font-default-dark);
- }
- }
-:global(:root[data-theme="dark"]) .label {
- color: var(--nord4);
-}
-:global(:root[data-theme="dark"]) .value {
- color: var(--font-default-dark);
-}
-
.payer-info {
display: flex;
align-items: center;
@@ -552,37 +420,19 @@
.splits-preview {
margin-bottom: 1.5rem;
padding: 1rem;
- background-color: var(--nord5);
+ background-color: var(--color-bg-tertiary);
border-radius: 0.5rem;
- border: 1px solid var(--nord4);
+ border: 1px solid var(--color-border);
}
.splits-preview h4 {
margin: 0 0 0.75rem 0;
font-size: 0.9rem;
- color: var(--nord2);
+ color: var(--color-text-secondary);
text-transform: uppercase;
letter-spacing: 0.5px;
}
- @media (prefers-color-scheme: dark) {
- :global(:root:not([data-theme="light"])) .splits-preview {
- background-color: var(--nord2);
- border-color: var(--nord3);
- }
-
- :global(:root:not([data-theme="light"])) .splits-preview h4 {
- color: var(--nord4);
- }
- }
-:global(:root[data-theme="dark"]) .splits-preview {
- background-color: var(--nord2);
- border-color: var(--nord3);
-}
-:global(:root[data-theme="dark"]) .splits-preview h4 {
- color: var(--nord4);
-}
-
.splits-list {
display: flex;
flex-direction: column;
@@ -598,7 +448,7 @@
.split-item .username {
flex: 1;
font-weight: 500;
- color: var(--nord0);
+ color: var(--color-text-primary);
}
.split-amount {
@@ -614,15 +464,6 @@
color: var(--red);
}
- @media (prefers-color-scheme: dark) {
- :global(:root:not([data-theme="light"])) .split-item .username {
- color: var(--font-default-dark);
- }
- }
-:global(:root[data-theme="dark"]) .split-item .username {
- color: var(--font-default-dark);
-}
-
.card-actions {
display: flex;
gap: 0.5rem;
@@ -657,35 +498,15 @@
}
.btn-secondary {
- background-color: var(--nord5);
- color: var(--nord0);
- border: 1px solid var(--nord4);
+ background-color: var(--color-bg-tertiary);
+ color: var(--color-text-primary);
+ border: 1px solid var(--color-border);
}
.btn-secondary:hover {
- background-color: var(--nord4);
+ background-color: var(--color-bg-elevated);
}
- @media (prefers-color-scheme: dark) {
- :global(:root:not([data-theme="light"])) .btn-secondary {
- background-color: var(--nord2);
- color: var(--font-default-dark);
- border-color: var(--nord3);
- }
-
- :global(:root:not([data-theme="light"])) .btn-secondary:hover {
- background-color: var(--nord3);
- }
- }
-:global(:root[data-theme="dark"]) .btn-secondary {
- background-color: var(--nord2);
- color: var(--font-default-dark);
- border-color: var(--nord3);
-}
-:global(:root[data-theme="dark"]) .btn-secondary:hover {
- background-color: var(--nord3);
-}
-
.btn-warning {
background-color: var(--orange);
color: white;
@@ -758,4 +579,4 @@
flex: 1;
}
}
-
\ No newline at end of file
+
diff --git a/src/routes/cospend/recurring/edit/[id]/+page.svelte b/src/routes/cospend/recurring/edit/[id]/+page.svelte
index 8385d45..e231b80 100644
--- a/src/routes/cospend/recurring/edit/[id]/+page.svelte
+++ b/src/routes/cospend/recurring/edit/[id]/+page.svelte
@@ -7,6 +7,7 @@
import ProfilePicture from '$lib/components/cospend/ProfilePicture.svelte';
import SplitMethodSelector from '$lib/components/cospend/SplitMethodSelector.svelte';
import UsersList from '$lib/components/cospend/UsersList.svelte';
+ import SaveFab from '$lib/components/SaveFab.svelte';
let { data } = $props();
@@ -288,9 +289,6 @@
{#if loadingPayment}
@@ -491,14 +489,7 @@
{error}
{/if}
-
- goto('/cospend/recurring')}>
- Cancel
-
-
- {loading ? 'Saving...' : 'Save Changes'}
-
-
+
{/if}
@@ -519,12 +510,7 @@
.header h1 {
margin: 0;
- color: var(--nord0);
- }
-
- .back-link {
- color: var(--blue);
- text-decoration: none;
+ color: var(--color-text-primary);
}
.loading {
@@ -540,17 +526,17 @@
}
.form-section {
- background: var(--nord6);
+ background: var(--color-surface);
padding: 1.5rem;
border-radius: 0.75rem;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
- border: 1px solid var(--nord4);
+ border: 1px solid var(--color-border);
}
.form-section h2 {
margin-top: 0;
margin-bottom: 1rem;
- color: var(--nord0);
+ color: var(--color-text-primary);
font-size: 1.25rem;
}
@@ -568,18 +554,18 @@
display: block;
margin-bottom: 0.5rem;
font-weight: 500;
- color: var(--nord3);
+ color: var(--color-text-secondary);
}
input, textarea, select {
width: 100%;
padding: 0.75rem;
- border: 1px solid var(--nord4);
+ border: 1px solid var(--color-border);
border-radius: 0.5rem;
font-size: 1rem;
box-sizing: border-box;
- background: var(--nord5);
- color: var(--nord0);
+ background: var(--color-bg-tertiary);
+ color: var(--color-text-primary);
}
input:focus, textarea:focus, select:focus {
@@ -594,16 +580,16 @@
.help-text {
margin-top: 0.5rem;
- color: var(--nord3);
+ color: var(--color-text-secondary);
font-size: 0.9rem;
}
.help-text code {
- background-color: var(--nord5);
+ background-color: var(--color-bg-tertiary);
padding: 0.125rem 0.25rem;
border-radius: 0.25rem;
font-family: monospace;
- color: var(--nord0);
+ color: var(--color-text-primary);
}
.help-text ul {
@@ -622,7 +608,7 @@
}
.execution-preview {
- background-color: var(--nord8);
+ background-color: var(--color-bg-tertiary);
border: 1px solid var(--blue);
border-radius: 0.5rem;
padding: 1rem;
@@ -643,17 +629,14 @@
}
.frequency-description {
- color: var(--nord3);
+ color: var(--color-text-secondary);
font-size: 0.9rem;
margin: 0;
font-style: italic;
}
-
-
-
.error {
- background-color: var(--nord6);
+ background-color: var(--color-bg-secondary);
color: var(--red);
padding: 1rem;
border-radius: 0.5rem;
@@ -661,177 +644,6 @@
border: 1px solid var(--red);
}
- .form-actions {
- display: flex;
- gap: 1rem;
- justify-content: flex-end;
- }
-
- .btn-primary, .btn-secondary {
- padding: 0.75rem 1.5rem;
- border-radius: 0.5rem;
- font-size: 1rem;
- cursor: pointer;
- transition: all 0.2s;
- }
-
- .btn-primary {
- background-color: var(--blue);
- color: white;
- border: none;
- }
-
- .btn-primary:hover:not(:disabled) {
- background-color: var(--lightblue);
- }
-
- .btn-primary:disabled {
- opacity: 0.6;
- cursor: not-allowed;
- }
-
- .btn-secondary {
- background-color: var(--nord5);
- color: var(--nord0);
- border: 1px solid var(--nord4);
- }
-
- .btn-secondary:hover {
- background-color: var(--nord4);
- }
-
- @media (prefers-color-scheme: dark) {
- :global(:root:not([data-theme="light"])) .header h1 {
- color: var(--font-default-dark);
- }
-
- :global(:root:not([data-theme="light"])) .form-section {
- background: var(--accent-dark);
- border-color: var(--nord2);
- }
-
- :global(:root:not([data-theme="light"])) .form-section h2 {
- color: var(--font-default-dark);
- }
-
- :global(:root:not([data-theme="light"])) label {
- color: var(--nord4);
- }
-
- :global(:root:not([data-theme="light"])) input,
-:global(:root:not([data-theme="light"])) textarea,
-:global(:root:not([data-theme="light"])) select {
- background: var(--nord1);
- color: var(--font-default-dark);
- border-color: var(--nord2);
- }
-
- :global(:root:not([data-theme="light"])) input:focus,
-:global(:root:not([data-theme="light"])) textarea:focus,
-:global(:root:not([data-theme="light"])) select:focus {
- box-shadow: 0 0 0 2px rgba(136, 192, 208, 0.2);
- }
-
- :global(:root:not([data-theme="light"])) .help-text {
- color: var(--nord4);
- }
-
- :global(:root:not([data-theme="light"])) .help-text code {
- background-color: var(--nord1);
- color: var(--font-default-dark);
- }
-
- :global(:root:not([data-theme="light"])) .execution-preview {
- background-color: var(--nord2);
- border-color: var(--blue);
- }
-
-
- :global(:root:not([data-theme="light"])) .error {
- background-color: var(--accent-dark);
- }
-
- :global(:root:not([data-theme="light"])) .btn-secondary {
- background-color: var(--nord1);
- color: var(--font-default-dark);
- border-color: var(--nord2);
- }
-
- :global(:root:not([data-theme="light"])) .btn-secondary:hover {
- background-color: var(--nord2);
- }
-
- :global(:root:not([data-theme="light"])) .conversion-preview.loading {
- background-color: var(--nord2);
- }
-
- :global(:root:not([data-theme="light"])) .conversion-preview.error {
- background-color: var(--accent-dark);
- }
-
- :global(:root:not([data-theme="light"])) .conversion-preview.success {
- background-color: var(--nord2);
- color: var(--font-default-dark);
- }
- }
-:global(:root[data-theme="dark"]) .header h1 {
- color: var(--font-default-dark);
-}
-:global(:root[data-theme="dark"]) .form-section {
- background: var(--accent-dark);
- border-color: var(--nord2);
-}
-:global(:root[data-theme="dark"]) .form-section h2 {
- color: var(--font-default-dark);
-}
-:global(:root[data-theme="dark"]) label {
- color: var(--nord4);
-}
-:global(:root[data-theme="dark"]) input,
-:global(:root[data-theme="dark"]) textarea,
-:global(:root[data-theme="dark"]) select {
- background: var(--nord1);
- color: var(--font-default-dark);
- border-color: var(--nord2);
-}
-:global(:root[data-theme="dark"]) input:focus,
-:global(:root[data-theme="dark"]) textarea:focus,
-:global(:root[data-theme="dark"]) select:focus {
- box-shadow: 0 0 0 2px rgba(136, 192, 208, 0.2);
-}
-:global(:root[data-theme="dark"]) .help-text {
- color: var(--nord4);
-}
-:global(:root[data-theme="dark"]) .help-text code {
- background-color: var(--nord1);
- color: var(--font-default-dark);
-}
-:global(:root[data-theme="dark"]) .execution-preview {
- background-color: var(--nord2);
- border-color: var(--blue);
-}
-:global(:root[data-theme="dark"]) .error {
- background-color: var(--accent-dark);
-}
-:global(:root[data-theme="dark"]) .btn-secondary {
- background-color: var(--nord1);
- color: var(--font-default-dark);
- border-color: var(--nord2);
-}
-:global(:root[data-theme="dark"]) .btn-secondary:hover {
- background-color: var(--nord2);
-}
-:global(:root[data-theme="dark"]) .conversion-preview.loading {
- background-color: var(--nord2);
-}
-:global(:root[data-theme="dark"]) .conversion-preview.error {
- background-color: var(--accent-dark);
-}
-:global(:root[data-theme="dark"]) .conversion-preview.success {
- background-color: var(--nord2);
- color: var(--font-default-dark);
-}
-
/* Amount-currency styling */
.amount-currency {
display: flex;
@@ -860,21 +672,21 @@
}
.conversion-preview.loading {
- background-color: var(--nord8);
+ background-color: var(--color-bg-tertiary);
border-color: var(--blue);
color: var(--blue);
}
.conversion-preview.error {
- background-color: var(--nord6);
+ background-color: var(--color-bg-secondary);
border-color: var(--red);
color: var(--red);
}
.conversion-preview.success {
- background-color: var(--nord14);
+ background-color: var(--color-bg-tertiary);
border-color: var(--green);
- color: var(--nord0);
+ color: var(--color-text-primary);
}
.conversion-preview small {
@@ -891,10 +703,6 @@
grid-template-columns: 1fr;
}
- .form-actions {
- flex-direction: column;
- }
-
.amount-currency {
flex-direction: column;
}
@@ -904,4 +712,5 @@
flex: none;
}
}
+
\ No newline at end of file
diff --git a/src/routes/fitness/[measure=fitnessMeasure]/+page.svelte b/src/routes/fitness/[measure=fitnessMeasure]/+page.svelte
index 7287be4..8ecc38d 100644
--- a/src/routes/fitness/[measure=fitnessMeasure]/+page.svelte
+++ b/src/routes/fitness/[measure=fitnessMeasure]/+page.svelte
@@ -1,22 +1,22 @@
+
+
{t('new_measurement', lang)} - Bocken
+
+
+
{t('new_measurement', lang)}
+
+
+
+
+
diff --git a/src/routes/fitness/[measure=fitnessMeasure]/edit/[id]/+page.server.ts b/src/routes/fitness/[measure=fitnessMeasure]/edit/[id]/+page.server.ts
new file mode 100644
index 0000000..edaae09
--- /dev/null
+++ b/src/routes/fitness/[measure=fitnessMeasure]/edit/[id]/+page.server.ts
@@ -0,0 +1,7 @@
+import type { PageServerLoad } from './$types';
+
+export const load: PageServerLoad = async ({ fetch, params }) => {
+ const res = await fetch(`/api/fitness/measurements/${params.id}`);
+ if (!res.ok) return { measurement: null };
+ return { measurement: await res.json() };
+};
diff --git a/src/routes/fitness/[measure=fitnessMeasure]/edit/[id]/+page.svelte b/src/routes/fitness/[measure=fitnessMeasure]/edit/[id]/+page.svelte
new file mode 100644
index 0000000..b139337
--- /dev/null
+++ b/src/routes/fitness/[measure=fitnessMeasure]/edit/[id]/+page.svelte
@@ -0,0 +1,256 @@
+
+
+
{t('edit_measurement', lang)} - Bocken
+
+
+
{t('edit_measurement', lang)}
+
+ {#if !m}
+
Measurement not found.
+ {:else}
+
+ {/if}
+
+
+