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 @@

{title}

- + {#if currentImage}
Receipt @@ -72,7 +72,7 @@
{/if} - + {#if imagePreview}
Receipt preview @@ -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 @@
@@ -612,14 +610,7 @@
{error}
{/if} -
- - Cancel - - -
+ @@ -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'} -
- - -
+ + {/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 @@
@@ -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 @@

Edit Recurring Payment

-
{#if loadingPayment} @@ -491,14 +489,7 @@
{error}
{/if} -
- - -
+ {/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)}

+ +
{ e.preventDefault(); saveMeasurement(); }}> +
+ + +
+ +

{t('general', lang)}

+
+
+ + +
+
+ + +
+
+ + +
+
+ +

{t('body_parts_cm', 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} +
{ e.preventDefault(); saveMeasurement(); }}> +
+ + +
+ +

{t('general', lang)}

+
+
+ + +
+
+ + +
+
+ + +
+
+ +

{t('body_parts_cm', lang)}

+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ +
+ +
+ + + + {/if} +
+ +