theming: migrate cospend to semantic CSS variables, extract SaveFab, refactor measure page

Replace hardcoded Nord colors with semantic CSS variables across all cospend
pages and shared components (FormSection, ImageUpload, SplitMethodSelector,
UsersList, PaymentModal, BarChart). Remove all dark mode override blocks.
Make BarChart font colors theme-reactive via isDark() + MutationObserver.

Extract reusable SaveFab component and use it on recipe edit and all cospend
edit/add pages. Remove Cancel buttons and back links in favor of browser
navigation. Replace raw checkboxes with Toggle component.

Move fitness measurement add/edit forms to separate routes with SaveFab.
Collapse profile section (sex/height) by default on the measure page.

Document theming rules in CLAUDE.md for future reference.
This commit is contained in:
2026-04-02 20:38:32 +02:00
parent 08a26ff4ac
commit 07610a498f
21 changed files with 927 additions and 2568 deletions
+4 -22
View File
@@ -13,35 +13,17 @@
<style>
.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);
}
</style>
</style>
+18 -86
View File
@@ -61,7 +61,7 @@
<div class="form-section">
<h2>{title}</h2>
{#if currentImage}
<div class="current-image">
<img src={currentImage} alt="Receipt" class="receipt-preview" />
@@ -72,7 +72,7 @@
</div>
</div>
{/if}
{#if imagePreview}
<div class="image-preview">
<img src={imagePreview} alt="Receipt preview" />
@@ -93,17 +93,17 @@
<small>JPEG, PNG, WebP (max 5MB)</small>
</div>
</label>
<input
type="file"
id="image"
accept="image/jpeg,image/jpg,image/png,image/webp"
<input
type="file"
id="image"
accept="image/jpeg,image/jpg,image/png,image/webp"
onchange={handleImageChange}
disabled={uploading}
hidden
/>
</div>
{/if}
{#if uploading}
<div class="upload-status">Uploading image...</div>
{/if}
@@ -111,114 +111,55 @@
<style>
.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);
}
.image-upload {
border: 2px dashed var(--nord4);
border: 2px dashed var(--color-border);
border-radius: 0.5rem;
padding: 2rem;
text-align: center;
cursor: pointer;
transition: all 0.2s;
background-color: var(--nord5);
background-color: var(--color-bg-tertiary);
}
.image-upload:hover {
border-color: var(--blue);
background-color: var(--nord4);
background-color: var(--color-bg-elevated);
}
@media (prefers-color-scheme: dark) {
:global(:root:not([data-theme="light"])) .image-upload {
background-color: var(--nord2);
border-color: var(--nord3);
}
:global(:root:not([data-theme="light"])) .image-upload:hover {
background-color: var(--nord3);
}
}
:global(:root[data-theme="dark"]) .image-upload {
background-color: var(--nord2);
border-color: var(--nord3);
}
:global(:root[data-theme="dark"]) .image-upload:hover {
background-color: var(--nord3);
}
.upload-label {
cursor: pointer;
display: block;
}
.upload-content svg {
color: var(--nord3);
color: var(--color-text-secondary);
margin-bottom: 1rem;
}
.upload-content p {
margin: 0 0 0.5rem 0;
font-weight: 500;
color: var(--nord0);
color: var(--color-text-primary);
}
.upload-content small {
color: var(--nord3);
color: var(--color-text-secondary);
}
@media (prefers-color-scheme: dark) {
:global(:root:not([data-theme="light"])) .upload-content svg {
color: var(--nord4);
}
:global(:root:not([data-theme="light"])) .upload-content p {
color: var(--font-default-dark);
}
:global(:root:not([data-theme="light"])) .upload-content small {
color: var(--nord4);
}
}
:global(:root[data-theme="dark"]) .upload-content svg {
color: var(--nord4);
}
:global(:root[data-theme="dark"]) .upload-content p {
color: var(--font-default-dark);
}
:global(:root[data-theme="dark"]) .upload-content small {
color: var(--nord4);
}
.image-preview {
text-align: center;
}
@@ -255,22 +196,13 @@
max-height: 200px;
object-fit: cover;
border-radius: 0.5rem;
border: 1px solid var(--nord4);
border: 1px solid var(--color-border);
margin-bottom: 0.75rem;
display: block;
margin-left: auto;
margin-right: auto;
}
@media (prefers-color-scheme: dark) {
:global(:root:not([data-theme="light"])) .receipt-preview {
border-color: var(--nord2);
}
}
:global(:root[data-theme="dark"]) .receipt-preview {
border-color: var(--nord2);
}
.image-actions {
display: flex;
justify-content: center;
@@ -282,4 +214,4 @@
font-size: 0.9rem;
text-align: center;
}
</style>
</style>
+51
View File
@@ -0,0 +1,51 @@
<script>
import Check from '$lib/assets/icons/Check.svelte';
let { disabled = false, onclick, label = 'Save', type = 'submit' } = $props();
</script>
<button
{type}
class="fab-save"
{onclick}
{disabled}
aria-label={label}
>
<Check fill="white" width="2rem" height="2rem" />
</button>
<style>
.fab-save {
position: fixed;
bottom: 0;
right: 0;
width: 1rem;
height: 1rem;
padding: 2rem;
margin: 2rem;
border: none;
border-radius: var(--radius-pill);
background-color: var(--red);
display: grid;
justify-content: center;
align-content: center;
cursor: pointer;
z-index: 100;
transition: background-color 0.2s;
}
.fab-save:hover, .fab-save:focus {
background-color: var(--nord11);
}
.fab-save:disabled {
opacity: 0.5;
cursor: not-allowed;
}
@media screen and (max-width: 500px) {
.fab-save {
margin: 1rem;
}
}
</style>
+23 -22
View File
@@ -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 @@
<style>
.chart-container {
background: var(--nord6);
border-radius: 0.75rem;
background: var(--color-surface);
border-radius: 12px;
padding: 1.5rem;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
border: 1px solid var(--nord4);
border: 1px solid var(--color-border);
}
@media (prefers-color-scheme: dark) {
:global(:root:not([data-theme="light"])) .chart-container {
background: var(--nord1);
border-color: var(--nord2);
}
}
:global(:root[data-theme="dark"]) .chart-container {
background: var(--nord1);
border-color: var(--nord2);
}
@media (max-width: 600px) {
.chart-container {
padding: 0.75rem;
+23 -201
View File
@@ -255,7 +255,7 @@
display: flex;
flex-direction: column;
height: 100%;
background: var(--nord6);
background: var(--color-bg-secondary);
}
.panel-header {
@@ -263,14 +263,13 @@
justify-content: space-between;
align-items: center;
padding: 1.5rem;
border-bottom: 1px solid var(--nord4);
background: var(--nord5);
background: var(--color-bg-tertiary);
flex-shrink: 0;
}
.panel-header h2 {
margin: 0;
color: var(--nord0);
color: var(--color-text-primary);
font-size: 1.25rem;
}
@@ -280,13 +279,13 @@
cursor: pointer;
padding: 0.5rem;
border-radius: 0.25rem;
color: var(--nord3);
color: var(--color-text-secondary);
transition: all 0.2s;
}
.close-button:hover {
background: var(--nord4);
color: var(--nord0);
background: var(--color-bg-elevated);
color: var(--color-text-primary);
}
.panel-body {
@@ -303,7 +302,7 @@
.error {
color: var(--red);
background-color: var(--nord6);
background-color: var(--color-bg-secondary);
border-radius: 0.5rem;
border: 1px solid var(--red);
}
@@ -318,8 +317,7 @@
justify-content: space-between;
align-items: flex-start;
padding: 1.5rem;
background: linear-gradient(135deg, var(--nord5), var(--nord4));
border-bottom: 1px solid var(--nord3);
background: var(--color-bg-tertiary);
}
.title-with-category {
@@ -336,7 +334,7 @@
.title-section h1 {
margin: 0;
color: var(--nord0);
color: var(--color-text-primary);
font-size: 1.5rem;
}
@@ -356,7 +354,7 @@
max-height: 100px;
object-fit: cover;
border-radius: 0.5rem;
border: 1px solid var(--nord4);
border: 1px solid var(--color-border);
}
.payment-info {
@@ -378,43 +376,41 @@
.label {
font-weight: 600;
color: var(--nord3);
color: var(--color-text-secondary);
font-size: 0.85rem;
text-transform: uppercase;
letter-spacing: 0.5px;
}
.value {
color: var(--nord0);
color: var(--color-text-primary);
font-size: 0.95rem;
}
.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: 1rem;
}
.description p {
margin: 0;
color: var(--nord2);
color: var(--color-text-tertiary);
line-height: 1.5;
font-size: 0.95rem;
}
.splits-section {
border-top: 1px solid var(--nord4);
padding: 1.5rem;
}
.splits-section h3 {
margin: 0 0 1rem 0;
color: var(--nord0);
color: var(--color-text-primary);
font-size: 1rem;
}
@@ -429,14 +425,12 @@
justify-content: space-between;
align-items: center;
padding: 0.75rem;
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);
}
.split-user {
@@ -453,7 +447,7 @@
.username {
font-weight: 500;
color: var(--nord0);
color: var(--color-text-primary);
font-size: 0.95rem;
}
@@ -481,8 +475,7 @@
.panel-actions {
padding: 1.5rem;
border-top: 1px solid var(--nord4);
background: var(--nord5);
background: var(--color-bg-tertiary);
display: flex;
gap: 1rem;
justify-content: flex-end;
@@ -495,190 +488,19 @@
font-size: 1rem;
cursor: pointer;
transition: all 0.2s;
border: none;
text-decoration: none;
display: inline-block;
text-align: center;
background-color: var(--nord5);
color: var(--nord0);
border: 1px solid var(--nord4);
background-color: var(--color-bg-primary);
color: var(--color-text-primary);
border: 1px solid var(--color-border);
}
.btn-secondary:hover {
background-color: var(--nord4);
background-color: var(--color-bg-elevated);
transform: translateY(-1px);
}
@media (prefers-color-scheme: dark) {
:global(:root:not([data-theme="light"])) .panel-content {
background: var(--nord1);
}
:global(:root:not([data-theme="light"])) .panel-header {
background: var(--nord2);
border-bottom-color: var(--nord3);
}
:global(:root:not([data-theme="light"])) .panel-header h2 {
color: var(--font-default-dark);
}
:global(:root:not([data-theme="light"])) .close-button {
color: var(--nord4);
}
:global(:root:not([data-theme="light"])) .close-button:hover {
background: var(--nord3);
color: var(--font-default-dark);
}
:global(:root:not([data-theme="light"])) .error {
background-color: var(--accent-dark);
}
:global(:root:not([data-theme="light"])) .payment-header {
background: linear-gradient(135deg, var(--nord2), var(--nord3));
}
:global(:root:not([data-theme="light"])) .title-section h1 {
color: var(--font-default-dark);
}
:global(:root:not([data-theme="light"])) .receipt-image img {
border-color: var(--nord2);
}
:global(:root:not([data-theme="light"])) .label {
color: var(--nord4);
}
:global(:root:not([data-theme="light"])) .value {
color: var(--font-default-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: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: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:not([data-theme="light"])) .username {
color: var(--font-default-dark);
}
:global(:root:not([data-theme="light"])) .panel-actions {
background: var(--nord2);
border-top-color: var(--nord3);
}
: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"]) .panel-content {
background: var(--nord1);
}
:global(:root[data-theme="dark"]) .panel-header {
background: var(--nord2);
border-bottom-color: var(--nord3);
}
:global(:root[data-theme="dark"]) .panel-header h2 {
color: var(--font-default-dark);
}
:global(:root[data-theme="dark"]) .close-button {
color: var(--nord4);
}
:global(:root[data-theme="dark"]) .close-button:hover {
background: var(--nord3);
color: var(--font-default-dark);
}
:global(:root[data-theme="dark"]) .error {
background-color: var(--accent-dark);
}
:global(:root[data-theme="dark"]) .payment-header {
background: linear-gradient(135deg, var(--nord2), var(--nord3));
}
:global(:root[data-theme="dark"]) .title-section h1 {
color: var(--font-default-dark);
}
:global(:root[data-theme="dark"]) .receipt-image img {
border-color: var(--nord2);
}
:global(:root[data-theme="dark"]) .label {
color: var(--nord4);
}
:global(:root[data-theme="dark"]) .value {
color: var(--font-default-dark);
}
: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);
}
: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);
}
: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);
}
:global(:root[data-theme="dark"]) .username {
color: var(--font-default-dark);
}
:global(:root[data-theme="dark"]) .panel-actions {
background: var(--nord2);
border-top-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);
}
@media (max-width: 768px) {
.panel-content {
height: 100vh;
@@ -216,38 +216,20 @@
<style>
.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;
}
@@ -256,27 +238,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);
}
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);
}
select:focus {
@@ -285,75 +258,31 @@
box-shadow: 0 0 0 2px rgba(94, 129, 172, 0.2);
}
@media (prefers-color-scheme: dark) {
: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"]) select {
background-color: var(--nord2);
color: var(--font-default-dark);
border-color: var(--nord3);
}
.proportional-splits, .personal-splits {
margin-top: 1rem;
}
.proportional-splits {
border: 1px solid var(--nord4);
border: 1px solid var(--color-border);
border-radius: 0.5rem;
padding: 1rem;
margin-bottom: 1rem;
background-color: var(--nord5);
background-color: var(--color-bg-tertiary);
}
@media (prefers-color-scheme: dark) {
:global(:root:not([data-theme="light"])) .proportional-splits {
border-color: var(--nord3);
background-color: var(--nord2);
}
}
:global(:root[data-theme="dark"]) .proportional-splits {
border-color: var(--nord3);
background-color: var(--nord2);
}
.proportional-splits h3, .personal-splits h3 {
margin-top: 0;
margin-bottom: 1rem;
color: var(--nord0);
color: var(--color-text-primary);
}
@media (prefers-color-scheme: dark) {
:global(:root:not([data-theme="light"])) .proportional-splits h3,
:global(:root:not([data-theme="light"])) .personal-splits h3 {
color: var(--font-default-dark);
}
}
:global(:root[data-theme="dark"]) .proportional-splits h3,
:global(:root[data-theme="dark"]) .personal-splits h3 {
color: var(--font-default-dark);
}
.personal-splits .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-splits .description {
color: var(--nord4);
}
}
:global(:root[data-theme="dark"]) .personal-splits .description {
color: var(--nord4);
}
.split-input {
display: flex;
align-items: center;
@@ -369,11 +298,11 @@
.split-input input {
max-width: 120px;
padding: 0.75rem;
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);
box-sizing: border-box;
}
@@ -383,52 +312,19 @@
box-shadow: 0 0 0 2px rgba(94, 129, 172, 0.2);
}
@media (prefers-color-scheme: dark) {
:global(:root:not([data-theme="light"])) .split-input input {
background-color: var(--nord2);
color: var(--font-default-dark);
border-color: var(--nord3);
}
}
:global(:root[data-theme="dark"]) .split-input input {
background-color: var(--nord2);
color: var(--font-default-dark);
border-color: var(--nord3);
}
.remainder-info {
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);
}
.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(--nord2);
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(--nord2);
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;
@@ -443,38 +339,18 @@
}
.split-preview {
background-color: var(--nord5);
background-color: var(--color-bg-tertiary);
padding: 1rem;
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-preview {
background-color: var(--nord2);
border-color: var(--nord3);
}
}
:global(:root[data-theme="dark"]) .split-preview {
background-color: var(--nord2);
border-color: var(--nord3);
}
.split-preview h3 {
margin-top: 0;
margin-bottom: 1rem;
color: var(--nord0);
color: var(--color-text-primary);
}
@media (prefers-color-scheme: dark) {
:global(:root:not([data-theme="light"])) .split-preview h3 {
color: var(--font-default-dark);
}
}
:global(:root[data-theme="dark"]) .split-preview h3 {
color: var(--font-default-dark);
}
.split-item {
display: flex;
justify-content: space-between;
@@ -489,18 +365,9 @@
}
.username {
color: var(--nord0);
color: var(--color-text-primary);
}
@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);
}
.amount.positive {
color: var(--green);
font-weight: 500;
@@ -510,4 +377,4 @@
color: var(--red);
font-weight: 500;
}
</style>
</style>
+16 -87
View File
@@ -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 @@
<div class="form-section">
<h2>Split Between Users</h2>
{#if predefinedMode}
<div class="predefined-users">
<p class="predefined-note">Splitting between predefined users:</p>
@@ -84,38 +84,20 @@
<style>
.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);
}
.users-list {
display: flex;
flex-wrap: wrap;
@@ -127,41 +109,21 @@
display: flex;
align-items: center;
gap: 0.5rem;
background-color: var(--nord5);
background-color: var(--color-bg-tertiary);
padding: 0.5rem 0.75rem;
border-radius: 1rem;
border: 1px solid var(--nord4);
border: 1px solid var(--color-border);
}
@media (prefers-color-scheme: dark) {
:global(:root:not([data-theme="light"])) .user-item {
background-color: var(--nord2);
border-color: var(--nord3);
}
}
:global(:root[data-theme="dark"]) .user-item {
background-color: var(--nord2);
border-color: var(--nord3);
}
.user-item.with-profile {
gap: 0.75rem;
}
.user-item .username {
font-weight: 500;
color: var(--nord0);
color: var(--color-text-primary);
}
@media (prefers-color-scheme: dark) {
:global(:root:not([data-theme="light"])) .user-item .username {
color: var(--font-default-dark);
}
}
:global(:root[data-theme="dark"]) .user-item .username {
color: var(--font-default-dark);
}
.you-badge {
background-color: var(--blue);
color: white;
@@ -172,39 +134,19 @@
}
.predefined-users {
background-color: var(--nord5);
background-color: var(--color-bg-tertiary);
padding: 1rem;
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"])) .predefined-users {
background-color: var(--nord2);
border-color: var(--nord3);
}
}
:global(:root[data-theme="dark"]) .predefined-users {
background-color: var(--nord2);
border-color: var(--nord3);
}
.predefined-note {
margin: 0 0 1rem 0;
color: var(--nord2);
color: var(--color-text-secondary);
font-size: 0.9rem;
font-style: italic;
}
@media (prefers-color-scheme: dark) {
:global(:root:not([data-theme="light"])) .predefined-note {
color: var(--nord4);
}
}
:global(:root[data-theme="dark"]) .predefined-note {
color: var(--nord4);
}
.remove-user {
background-color: var(--red);
color: white;
@@ -229,11 +171,11 @@
.add-user input {
flex: 1;
padding: 0.75rem;
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);
box-sizing: border-box;
}
@@ -243,19 +185,6 @@
box-shadow: 0 0 0 2px rgba(94, 129, 172, 0.2);
}
@media (prefers-color-scheme: dark) {
:global(:root:not([data-theme="light"])) .add-user input {
background-color: var(--nord2);
color: var(--font-default-dark);
border-color: var(--nord3);
}
}
:global(:root[data-theme="dark"]) .add-user input {
background-color: var(--nord2);
color: var(--font-default-dark);
border-color: var(--nord3);
}
.add-user button {
background-color: var(--blue);
color: white;
@@ -270,4 +199,4 @@
background-color: var(--nord10);
transform: translateY(-1px);
}
</style>
</style>