From 3055ce53c18d63023f5216418efb831c82fcec94 Mon Sep 17 00:00:00 2001 From: ulfrxdev Date: Sat, 18 Apr 2026 12:15:51 +0200 Subject: [PATCH] Light mode --- index.html | 111 +++++++++++++++++++------------------ js/ui/ingredientCard.js | 2 +- js/ui/mealPlanEditor.js | 8 +-- js/ui/recipeGrid.js | 2 +- js/ui/recipeSearchField.js | 2 +- js/views/Filter.js | 7 +-- js/views/MealPlanner.js | 12 ++-- js/views/Pantry.js | 27 +++++---- js/views/RecipeDetailV2.js | 14 ++--- js/views/RecipeList.js | 15 ++--- js/views/ShoppingList.js | 9 ++- 11 files changed, 104 insertions(+), 105 deletions(-) diff --git a/index.html b/index.html index 761ab0b..9dd6b3d 100644 --- a/index.html +++ b/index.html @@ -23,42 +23,46 @@ :root { color-scheme: light; --app-font: 'Plus Jakarta Sans', 'Segoe UI', sans-serif; - --app-bg-rgb: 243, 239, 233; - --surface-rgb: 255, 255, 255; - --surface-soft-rgb: 247, 242, 236; - --surface-strong-rgb: 235, 229, 221; - --line-rgb: 69, 58, 48; - --text-primary-rgb: 28, 24, 21; - --text-secondary-rgb: 102, 92, 83; - --text-tertiary-rgb: 156, 146, 137; - --warm-rgb: 183, 142, 88; - --success-rgb: 98, 171, 132; - --danger-rgb: 210, 116, 116; + --app-bg-rgb: 243, 239, 233; /* #f3efe9 — warm cream base */ + --surface-rgb: 255, 255, 255; /* #ffffff — white panels (existing tokens) */ + --surface-soft-rgb: 249, 245, 238; /* #f9f5ee */ + --surface-strong-rgb: 235, 229, 220; /* #ebe5dc */ + --line-rgb: 69, 58, 48; /* #453a30 — divider base (warm brown) */ + --text-primary-rgb: 28, 24, 21; /* #1c1815 */ + --text-secondary-rgb: 102, 92, 83; /* #665c53 */ + --text-tertiary-rgb: 140, 130, 118; /* #8c8276 */ + --warm-rgb: 183, 142, 88; /* #b78e58 — caramel */ + --success-rgb: 47, 133, 82; /* #2f8552 — deep emerald (AA on white) */ + --danger-rgb: 187, 75, 75; /* #bb4b4b — deep rose (AA on white) */ --panel-shadow: 0 18px 40px rgba(24, 17, 11, 0.08); --panel-shadow-strong: 0 24px 60px rgba(24, 17, 11, 0.16); --dock-shadow: 0 24px 56px rgba(24, 17, 11, 0.18); - --highlight-top: rgba(111, 149, 255, 0.14); - --highlight-bottom: rgba(97, 184, 180, 0.12); + --highlight-top: transparent; + --highlight-bottom: transparent; - /* Extended palette (placeholder light-mode values — light mode is WIP). */ - --card-rgb: 255, 255, 255; - --card-soft-rgb: 250, 246, 240; - --card-strong-rgb: 235, 229, 221; - --card-raised-rgb: 252, 248, 242; - --sunken-rgb: 247, 242, 236; - --sunken-deep-rgb: 235, 229, 221; - --border-card-rgb: 220, 212, 200; - --border-input-rgb: 176, 164, 150; - --text-emphasis-rgb: 14, 12, 10; - --text-body-rgb: 48, 40, 33; - --text-body-soft-rgb: 72, 62, 52; - --text-muted-rgb: 112, 102, 91; - --text-dim-rgb: 140, 130, 118; - --text-faint-rgb: 156, 146, 137; - --text-subdued-rgb: 176, 166, 154; - --skeleton-rgb: 226, 220, 210; - --on-accent-rgb: 255, 255, 255; - --overlay-rgb: 24, 17, 11; + /* Extended light palette — mirrors dark hierarchy: sunken < app-bg < card. */ + --card-rgb: 255, 255, 255; /* #ffffff — primary elevated card (raised via shadow) */ + --card-soft-rgb: 239, 233, 221; /* #efe9dd — nested/medium surface on white */ + --card-strong-rgb: 228, 219, 205; /* #e4dbcd — strong surface / stroke */ + --card-raised-rgb: 252, 249, 242; /* #fcf9f2 — subtle raise (chip on card) */ + --sunken-rgb: 235, 229, 217; /* #ebe5d9 — deep inputs / search shell */ + --sunken-deep-rgb: 219, 211, 196; /* #dbd3c4 — deepest well */ + --border-card-rgb: 224, 215, 200; /* #e0d7c8 — subtle card/dock border */ + --border-input-rgb: 180, 168, 150; /* #b4a896 — input / active border */ + --text-emphasis-rgb: 14, 12, 10; /* #0e0c0a — brightest interactive text */ + --text-body-rgb: 48, 40, 33; /* #302821 — primary body text (most common) */ + --text-body-soft-rgb: 72, 62, 52; /* #483e34 — body soft */ + --text-muted-rgb: 102, 92, 83; /* #665c53 — muted (matches --text-secondary) */ + --text-dim-rgb: 140, 130, 118; /* #8c8276 — dim / placeholder */ + --text-faint-rgb: 156, 146, 137; /* #9c9289 — faint icon color */ + --text-subdued-rgb: 176, 166, 154; /* #b0a69a — subdued */ + --skeleton-rgb: 226, 220, 210; /* #e2dcd2 — image loading placeholder */ + --on-accent-rgb: 255, 255, 255; /* white text on accent backgrounds */ + --overlay-rgb: 24, 17, 11; /* #18110b — scrim / shadow base (warm brown-black) */ + --shadow-card: 0 2px 8px rgba(24, 17, 11, 0.08); + --shadow-shell: 0 5px 10px rgba(24, 17, 11, 0.08), 0 14px 22px rgba(24, 17, 11, 0.12), 0 22px 34px rgba(24, 17, 11, 0.10), inset 0 1px 0 rgba(255, 255, 255, 0.5); + --icon-watermark: rgba(24, 17, 11, 0.08); + --hover-overlay: rgba(24, 17, 11, 0.05); } .dark { @@ -99,6 +103,10 @@ --skeleton-rgb: 212, 212, 212; /* #d4d4d4 — image loading placeholder */ --on-accent-rgb: 26, 26, 26; /* #1a1a1a — text on bright accent backgrounds */ --overlay-rgb: 0, 0, 0; /* scrim / shadow base */ + --shadow-card: 0 2px 8px rgba(0, 0, 0, 0.25); + --shadow-shell: 0 5px 10px rgba(0, 0, 0, 0.16), 0 14px 22px rgba(0, 0, 0, 0.24), 0 22px 34px rgba(0, 0, 0, 0.18), inset 0 1px 0 rgba(255, 255, 255, 0.04); + --icon-watermark: rgba(255, 255, 255, 0.10); + --hover-overlay: rgba(255, 255, 255, 0.05); } * { touch-action: manipulation; } @@ -124,7 +132,7 @@ border-radius: 50%; background: rgb(var(--text-body-rgb)); border: 2px solid rgba(var(--surface-rgb), 0.9); - box-shadow: 0 8px 20px rgba(0, 0, 0, 0.22); + box-shadow: 0 8px 20px rgba(var(--overlay-rgb), 0.22); cursor: pointer; margin-top: -8px; } @@ -155,8 +163,12 @@ .bg-gray-100 { background-color: rgba(var(--surface-soft-rgb), 0.92) !important; } .bg-gray-200 { background-color: rgba(var(--surface-strong-rgb), 0.94) !important; } .bg-gray-900 { + background: rgb(var(--text-primary-rgb)) !important; + box-shadow: 0 2px 8px rgba(var(--overlay-rgb), 0.14) !important; + } + .dark .bg-gray-900 { background: linear-gradient(180deg, rgba(var(--surface-strong-rgb), 1) 0%, rgba(var(--surface-soft-rgb), 1) 100%) !important; - box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.08), 0 12px 28px rgba(0, 0, 0, 0.18) !important; + box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.08), 0 12px 28px rgba(var(--overlay-rgb), 0.18) !important; } .border-gray-900 { border-color: rgba(var(--text-body-rgb), 0.42) !important; } .bg-white\/90 { background-color: rgba(var(--surface-rgb), 0.9) !important; } @@ -189,7 +201,8 @@ .hover\:bg-gray-50:hover { background-color: rgba(var(--surface-soft-rgb), 0.94) !important; } .hover\:bg-gray-100:hover { background-color: rgba(var(--surface-strong-rgb), 0.94) !important; } .hover\:bg-white:hover { background-color: rgba(var(--surface-rgb), 0.98) !important; } - .hover\:bg-black:hover { background-color: rgba(var(--surface-strong-rgb), 1) !important; } + .hover\:bg-black:hover { background-color: rgb(var(--text-emphasis-rgb)) !important; } + .dark .hover\:bg-black:hover { background-color: rgba(var(--surface-strong-rgb), 1) !important; } .hover\:bg-red-50:hover { background-color: rgba(var(--danger-rgb), 0.12) !important; } .hover\:text-gray-700:hover, .hover\:text-gray-900:hover, @@ -433,11 +446,8 @@ background: rgb(var(--card-rgb)) !important; border: 1px solid rgb(var(--border-card-rgb)) !important; box-shadow: - 0 5px 10px rgba(0, 0, 0, 0.16), - 0 14px 22px rgba(0, 0, 0, 0.24), - 0 22px 34px rgba(0, 0, 0, 0.18), - inset 0 1px 0 rgba(255, 255, 255, 0.04), - inset 0 2px 6px rgba(0, 0, 0, 0.16), + var(--shadow-shell), + inset 0 2px 6px rgba(var(--overlay-rgb), 0.16), inset 0 -1px 2px rgba(255, 255, 255, 0.02) !important; backdrop-filter: blur(24px); -webkit-backdrop-filter: blur(24px); @@ -450,7 +460,7 @@ bottom: -0.72rem; height: 1.05rem; border-radius: 999px; - background: rgba(0, 0, 0, 0.36); + background: rgba(var(--overlay-rgb), 0.36); filter: blur(12px); opacity: 0.9; z-index: -1; @@ -460,11 +470,8 @@ background: rgb(var(--card-rgb)) !important; border: 1px solid rgba(var(--border-input-rgb), 0.62) !important; box-shadow: - 0 6px 12px rgba(0, 0, 0, 0.18), - 0 16px 24px rgba(0, 0, 0, 0.24), - 0 24px 36px rgba(0, 0, 0, 0.18), - inset 0 1px 0 rgba(255, 255, 255, 0.05), - inset 0 2px 7px rgba(0, 0, 0, 0.18), + var(--shadow-shell), + inset 0 2px 7px rgba(var(--overlay-rgb), 0.18), inset 0 -1px 2px rgba(255, 255, 255, 0.03) !important; } #planner-picker-search { @@ -492,7 +499,7 @@ box-shadow: none !important; } #planner-picker-filter-btn:hover { - background: rgba(255, 255, 255, 0.03) !important; + background: var(--hover-overlay) !important; } #planner-picker-sheet, #planner-ing-sheet, @@ -546,10 +553,8 @@ background: rgb(var(--card-rgb)); border: 1px solid rgb(var(--border-card-rgb)); box-shadow: - inset 0 1px 8px rgba(0, 0, 0, 0.15), - 0 5px 10px rgba(0, 0, 0, 0.16), - 0 14px 22px rgba(0, 0, 0, 0.24), - 0 22px 34px rgba(0, 0, 0, 0.18); + inset 0 1px 8px rgba(var(--overlay-rgb), 0.15), + var(--shadow-shell); pointer-events: auto; } #app-bottom-nav .nav-slot { @@ -592,7 +597,7 @@ #app-bottom-nav .nav-action:hover { transform: translateY(-1px); color: rgb(var(--text-primary-rgb)); - background: rgba(255, 255, 255, 0.04) !important; + background: var(--hover-overlay) !important; } #app-bottom-nav .nav-tab.is-active { width: 100%; @@ -609,7 +614,7 @@ #app-bottom-nav button:focus-visible { outline: none; box-shadow: - 0 0 0 3px rgba(255, 255, 255, 0.08), + 0 0 0 3px var(--hover-overlay), 0 0 0 6px rgba(var(--text-body-rgb), 0.26) !important; } @media (max-width: 380px) { diff --git a/js/ui/ingredientCard.js b/js/ui/ingredientCard.js index f9030ca..cea5641 100644 --- a/js/ui/ingredientCard.js +++ b/js/ui/ingredientCard.js @@ -152,7 +152,7 @@ function getQtyStepMeta(def, product = null) { export function getIngredientCardHTML({ idBase, overlayClass = 'fixed inset-0 z-[70] hidden opacity-0 transition-opacity duration-200 flex items-center justify-center p-5', - overlayStyle = 'pointer-events:none; background:rgba(0,0,0,0.5);', + overlayStyle = 'pointer-events:none; background:rgba(var(--overlay-rgb),0.5);', cardClass = 'relative w-full max-w-xs rounded-2xl shadow-2xl overflow-hidden', cardStyle = 'background:rgb(var(--app-bg-rgb)); pointer-events:auto; max-height:85vh; overflow-y:auto; transform:translateY(0.75rem); opacity:0; transition:transform 220ms ease, opacity 220ms ease;', } = {}) { diff --git a/js/ui/mealPlanEditor.js b/js/ui/mealPlanEditor.js index a65f0bf..7364097 100644 --- a/js/ui/mealPlanEditor.js +++ b/js/ui/mealPlanEditor.js @@ -45,7 +45,7 @@ export function getMealPlanEditorHTML() {

- @@ -69,7 +69,7 @@ export function getMealPlanEditorHTML() {
-
+
@@ -245,7 +245,7 @@ export function setupMealPlanEditor() { el.innerHTML = `

Porcje

-
+
@@ -269,7 +269,7 @@ export function setupMealPlanEditor() { const removeBtn = (cls, attrs) => ``; const ingredientRowClass = 'mpe-ing-row rounded-xl px-3 py-3'; - const ingredientRowStyle = 'background:rgb(var(--card-rgb)) !important; background-image:none !important; box-shadow:0 2px 8px rgba(0,0,0,0.25) !important; border:none !important;'; + const ingredientRowStyle = 'background:rgb(var(--card-rgb)) !important; background-image:none !important; box-shadow:var(--shadow-card) !important; border:none !important;'; for (const ing of r.ingredients) { const id = ing.ingredientId; diff --git a/js/ui/recipeGrid.js b/js/ui/recipeGrid.js index f35954d..28135ed 100644 --- a/js/ui/recipeGrid.js +++ b/js/ui/recipeGrid.js @@ -33,7 +33,7 @@ function renderRecipeCard(recipe, { showSlotLabels = true, cardClassName = '' } const className = ['recipe-browser-card', cardClassName].filter(Boolean).join(' '); return ` - @@ -180,7 +179,7 @@ function getChipStyle(active) { const color = active ? FILTER_TEXT_ACTIVE : FILTER_TEXT_SECONDARY; const borderRule = active ? `border:1px solid ${FILTER_BORDER};` : 'border:none;'; const shadow = active - ? 'box-shadow:inset 0 1px 0 rgba(255,255,255,0.04), 0 0 0 1px rgba(0,0,0,0.08);' + ? 'box-shadow:inset 0 1px 0 rgba(255,255,255,0.04), 0 0 0 1px rgba(var(--overlay-rgb),0.08);' : ''; return `background:${background}; ${borderRule} color:${color}; ${shadow}`; } diff --git a/js/views/MealPlanner.js b/js/views/MealPlanner.js index 4e5b8c6..bf537b5 100644 --- a/js/views/MealPlanner.js +++ b/js/views/MealPlanner.js @@ -161,7 +161,7 @@ export function getMealPlannerHTML() {
-