From 76135e404a29c0d3e93210d31198540baaf7c12d Mon Sep 17 00:00:00 2001 From: Davide Grilli Date: Wed, 25 Mar 2026 08:20:57 +0100 Subject: [PATCH] Migliora UI: design moderno, accordion pasti, fix UX - style.css: shadows, transizioni, variabili --radius-sm/full, --color-primary-muted, --color-danger-muted - BottomNav: icone SVG cross-platform, indicatore pill attivo, shadow verso l'alto - MealCard: accordion (solo oggi aperto di default), badge voci quando chiusa, icone pasto, fix touch target btn-remove - MealPlanner: rileva giorno corrente, mostra come sottotitolo - Converter: chip alimento selezionato, result box con formula (es. 140g x 0.75 = 105g), layout migliorato - ShoppingList: contatore X/Y completati, sezione separata voci spuntate, btn-clear ghost invece di solid rosso, empty state - CheckboxItem: touch target 44px garantito, transizione checked, icona SVG per rimuovere, fix plurale "1 voce / N voci" Co-Authored-By: Claude Sonnet 4.6 --- src/components/BottomNav.vue | 59 ++++++++++-- src/components/CheckboxItem.vue | 37 +++++-- src/components/MealCard.vue | 165 +++++++++++++++++++++++--------- src/pages/Converter.vue | 158 +++++++++++++++++++++++------- src/pages/MealPlanner.vue | 10 +- src/pages/ShoppingList.vue | 126 +++++++++++++++++++----- src/style.css | 60 ++++++++---- 7 files changed, 476 insertions(+), 139 deletions(-) diff --git a/src/components/BottomNav.vue b/src/components/BottomNav.vue index 5489ddb..c8f5add 100644 --- a/src/components/BottomNav.vue +++ b/src/components/BottomNav.vue @@ -5,8 +5,9 @@ :key="tab.id" :class="['nav-btn', { active: modelValue === tab.id }]" @click="$emit('update:modelValue', tab.id)" + :aria-label="tab.label" > - {{ tab.icon }} + {{ tab.label }} @@ -17,9 +18,35 @@ defineProps({ modelValue: String }) defineEmits(['update:modelValue']) const tabs = [ - { id: 'meal', icon: 'πŸ“…', label: 'Pasti' }, - { id: 'convert', icon: 'βš–οΈ', label: 'Converti' }, - { id: 'shop', icon: 'πŸ›’', label: 'Spesa' }, + { + id: 'meal', + label: 'Pasti', + icon: ` + + + + + `, + }, + { + id: 'convert', + label: 'Converti', + icon: ` + + + + + `, + }, + { + id: 'shop', + label: 'Spesa', + icon: ` + + + + `, + }, ] @@ -36,6 +63,7 @@ const tabs = [ border-top: 1px solid var(--color-border); display: flex; z-index: 100; + box-shadow: 0 -4px 16px rgba(0, 0, 0, 0.06); } .nav-btn { @@ -44,24 +72,39 @@ const tabs = [ flex-direction: column; align-items: center; justify-content: center; - gap: 2px; + gap: 3px; background: none; border-radius: 0; color: var(--color-muted); min-height: unset; padding: 0; - font-size: 0.7rem; + position: relative; + transition: color var(--transition); } .nav-btn.active { color: var(--color-primary); } +/* indicatore attivo: pill sopra l'icona β€” segnala la tab senza aggressivitΓ  */ +.nav-btn.active::before { + content: ''; + position: absolute; + top: 6px; + width: 28px; + height: 3px; + background: var(--color-primary); + border-radius: var(--radius-full); +} + .nav-icon { - font-size: 1.2rem; + display: flex; + align-items: center; + justify-content: center; } .nav-label { - font-size: 0.7rem; + font-size: 0.68rem; + font-weight: 500; } diff --git a/src/components/CheckboxItem.vue b/src/components/CheckboxItem.vue index 9b7a3f2..16fe178 100644 --- a/src/components/CheckboxItem.vue +++ b/src/components/CheckboxItem.vue @@ -4,7 +4,11 @@ {{ item.name }} - + @@ -19,9 +23,17 @@ defineEmits(['toggle', 'remove']) align-items: center; justify-content: space-between; background: var(--color-surface); - border-radius: var(--radius); - padding: 12px 14px; - border: 1px solid var(--color-border); + border-radius: var(--radius-sm); + padding: 4px 4px 4px 14px; + border: 1.5px solid var(--color-border); + box-shadow: var(--shadow-sm); + transition: background var(--transition), border-color var(--transition); +} + +.checkbox-item.checked { + background: var(--color-bg); + border-color: transparent; + box-shadow: none; } .item-label { @@ -30,6 +42,7 @@ defineEmits(['toggle', 'remove']) gap: 12px; cursor: pointer; flex: 1; + padding: 8px 0; } input[type="checkbox"] { @@ -37,10 +50,12 @@ input[type="checkbox"] { height: 20px; cursor: pointer; accent-color: var(--color-primary); + flex-shrink: 0; } .item-name { font-size: 1rem; + transition: color var(--transition); } .checked .item-name { @@ -48,11 +63,19 @@ input[type="checkbox"] { color: var(--color-muted); } +/* touch target pieno 44Γ—44px */ .btn-remove { background: none; color: var(--color-muted); - min-height: unset; - padding: 0 4px; - font-size: 0.8rem; + min-height: 44px; + min-width: 44px; + padding: 0; + display: flex; + align-items: center; + justify-content: center; + border-radius: var(--radius-sm); + flex-shrink: 0; } + +.btn-remove:active { color: var(--color-danger); } diff --git a/src/components/MealCard.vue b/src/components/MealCard.vue index 9443670..157abed 100644 --- a/src/components/MealCard.vue +++ b/src/components/MealCard.vue @@ -1,47 +1,71 @@ diff --git a/src/pages/MealPlanner.vue b/src/pages/MealPlanner.vue index b4a5612..c9ddbac 100644 --- a/src/pages/MealPlanner.vue +++ b/src/pages/MealPlanner.vue @@ -1,11 +1,15 @@