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:
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
@@ -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;
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
|
||||
Reference in New Issue
Block a user