diff --git a/relay/ui/app.js b/relay/ui/app.js
index e8903b9..4be75a5 100644
--- a/relay/ui/app.js
+++ b/relay/ui/app.js
@@ -773,7 +773,14 @@ async function loadShopping(quiet = false) {
const list = $('shopping-items');
if (!list) return;
if (!data?.ok) { if (!quiet) shoppingErr(data?.error || 'load failed'); return; }
- const lists = data.lists || [];
+ // Dedup by card_uid — belt and suspenders in case the relay DB
+ // has stale rows from earlier schema migrations.
+ const seen = new Set();
+ const lists = (data.lists || []).filter(l => {
+ if (seen.has(l.card_uid)) return false;
+ seen.add(l.card_uid);
+ return true;
+ });
if (!lists.length) {
if (title) title.textContent = 'Shopping';
list.innerHTML = '
no active shopping lists';
diff --git a/relay/ui/style.css b/relay/ui/style.css
index 28cc96a..b44f8e9 100644
--- a/relay/ui/style.css
+++ b/relay/ui/style.css
@@ -267,16 +267,8 @@ label.checkbox input[type="checkbox"] { accent-color:var(--accent); cursor:point
unchecked items only, tap to flip. */
.shopping-wrap { max-width: 520px; margin: 0 auto; display: flex; flex-direction: column; gap: 12px; }
.shopping-top { display: flex; align-items: center; gap: 10px; padding: 6px 2px; }
-.shopping-items { list-style: none; padding: 0; margin: 0; display: flex; flex-direction: column; gap: 6px; }
-.shopping-items li {
- background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius-lg);
- padding: 14px 16px; font-size: 16px; cursor: pointer; user-select: none;
- -webkit-tap-highlight-color: transparent;
- transition: transform 0.12s, opacity 0.3s, background 0.12s;
-}
-.shopping-items li:active { transform: scale(0.98); background: var(--raised, var(--surface)); }
-.shopping-items li.checked { opacity: 0.35; text-decoration: line-through; }
-.shopping-items .empty { text-align: center; padding: 40px 16px; color: var(--dim); background: transparent; border: none; cursor: default; list-style: none; }
+.shopping-items { list-style: none; padding: 0; margin: 0; display: flex; flex-direction: column; gap: 10px; }
+.shopping-items .empty { list-style: none; text-align: center; padding: 40px 16px; color: var(--dim); background: transparent; border: none; cursor: default; }
.shopping-items .empty:active { transform: none; }
/* Multi-list stacked boxes */