// Flavor catalog — 50 flavors split across two shops.
//   'algade'  → Algade Is   (city shop — classic, comforting)
//   'havnens' → Havnens Is  (harbor shop — seasonal, adventurous)
//
// Optional rich fields used by the modal:
//   long, ingredients, allergens, churned, face
//
// `seed: true` marks the curated default selection that ships when no admin
// picks have been saved yet (so the public site doesn't show all 50 by default).

const FLAVORS = [
  // ─── Algade Is (25) ──────────────────────────────────────────────────────
  {
    id: 'pist', store: 'algade', name: 'Pistachio Cream',
    desc: 'Sicilian pistachios stone-ground into Jersey cream, with a touch of wildflower honey.',
    color: 'var(--pistachio)', deep: 'var(--pistachio-deep)', bg: '#D8E2B8',
    img: 'images/pistachio.webp',
    price: 38, tags: ['popular', 'vegetarian'], sold: false, seed: true,
    long: 'We stone-grind whole Bronte pistachios into a paste, fold it into our Jersey cream base, and finish with a thread of Roskilde wildflower honey. The result is unmistakably nutty, never green-dyed, never overly sweet — the way pistachio ought to taste.',
    ingredients: ['Organic Jersey cream', 'Bronte pistachio paste (28%)', 'Egg yolks', 'Cane sugar', 'Wildflower honey', 'Sea salt'],
    allergens: ['Mælk', 'Æg', 'Pistacie'], churned: 'This morning, 06:14',
  },
  {
    id: 'cookie', store: 'algade', name: 'Cookie Dough',
    desc: 'Vanilla bean cream packed with raw cookie dough chunks and dark chocolate shards.',
    color: '#E8D5A8', deep: '#7A5230', bg: '#E4F0F3',
    img: 'images/cookiedough.webp',
    price: 40, tags: ['popular', 'new'], sold: false, seed: true,
    long: 'Vanilla bean cream stuffed to the rafters with handmade cookie dough — flour, brown sugar, soft butter, the works — plus shards of 70% dark chocolate that crack when your spoon goes through. The dough is heat-treated and food-safe.',
    ingredients: ['Organic Jersey cream', 'Bourbon vanilla', 'Heat-treated wheat flour', 'Brown sugar cookie dough', 'Dark chocolate 70%', 'Egg yolks', 'Sea salt'],
    allergens: ['Mælk', 'Æg', 'Hvede', 'Gluten', 'Soja'], churned: 'This morning, 06:25',
  },
  {
    id: 'straw', store: 'algade', name: 'Strawberry Basil',
    desc: 'Field strawberries with a torn-leaf basil sorbet swirl.',
    color: 'var(--strawberry)', deep: 'var(--strawberry-deep)', bg: '#FDECEE',
    price: 36, tags: ['seasonal', 'sorbet', 'vegan'], sold: false, face: 'love', seed: true,
    long: 'Late-June strawberries from a single farm outside Lejre, blitzed with torn basil leaves and a squeeze of lemon. No dairy, no thickeners — just fruit and patience.',
    ingredients: ['Lejre strawberries (62%)', 'Cane sugar', 'Fresh basil', 'Lemon juice'],
    allergens: [], churned: 'This morning, 05:48',
  },
  {
    id: 'choc', store: 'algade', name: 'Dark Chocolate',
    desc: '72% Valrhona, a hint of smoked salt, slow-churned.',
    color: 'var(--chocolate)', deep: 'var(--chocolate-deep)', bg: '#F0E4D8',
    price: 38, tags: ['popular'], sold: false, face: 'cool', seed: true,
    long: 'Cold-steep cocoa nibs overnight, melt Valrhona Caraïbe into hot cream, age the base 24 hours, then slow-churn. Finished with a whisper of Maldon smoked salt.',
    ingredients: ['Organic Jersey cream', 'Valrhona Caraïbe 66%', 'Cocoa nibs', 'Egg yolks', 'Cane sugar', 'Maldon salt'],
    allergens: ['Mælk', 'Æg'], churned: 'This morning, 07:02',
  },
  {
    id: 'van', store: 'algade', name: 'Bourbon Vanilla',
    desc: 'Split Madagascar pods, organic Jersey cream.',
    color: 'var(--vanilla)', deep: 'var(--vanilla-deep)', bg: '#FBF5E2',
    price: 34, tags: ['popular'], sold: false, face: 'happy', seed: true,
    long: 'The most honest scoop in the case. Two split Madagascar pods per batch, scraped into warm cream the night before. No extract, no shortcuts.',
    ingredients: ['Organic Jersey cream', 'Whole milk', 'Madagascar vanilla pods', 'Egg yolks', 'Cane sugar'],
    allergens: ['Mælk', 'Æg'], churned: 'This morning, 05:30',
  },
  {
    id: 'lav', store: 'algade', name: 'Lavender Lemon',
    desc: 'Provençal lavender, candied lemon peel, cream.',
    color: 'var(--lavender)', deep: 'var(--lavender-deep)', bg: '#F1ECF6',
    price: 38, tags: ['new', 'seasonal'], sold: true, face: 'sleepy', seed: true,
    long: 'Hand-rubbed Provençal lavender steeped in warm cream until it goes from floral to honeyed. Folded with candied Amalfi lemon peel.',
    ingredients: ['Organic Jersey cream', 'Provençal lavender', 'Candied Amalfi lemon peel', 'Egg yolks', 'Cane sugar'],
    allergens: ['Mælk', 'Æg'], churned: 'Sold out today',
  },
  {
    id: 'coff', store: 'algade', name: 'Burnt Caramel Coffee',
    desc: 'Single-origin Ethiopian espresso, dark caramel ribbon.',
    color: 'var(--coffee)', deep: 'var(--coffee-deep)', bg: '#F2E7D8',
    price: 40, tags: ['popular'], sold: false, face: 'wow', seed: true,
    long: 'A double espresso of Ethiopian Yirgacheffe pulled into hot cream, then ribboned with caramel pushed just past the edge of burnt.',
    ingredients: ['Organic Jersey cream', 'Yirgacheffe espresso', 'Caramelised cane sugar', 'Egg yolks', 'Sea salt'],
    allergens: ['Mælk', 'Æg'], churned: 'This morning, 06:40',
  },
  {
    id: 'cher', store: 'algade', name: 'Sour Cherry Almond',
    desc: 'Morello cherries, toasted almonds, marzipan crumble.',
    color: 'var(--cherry)', deep: 'var(--cherry-deep)', bg: '#FAE4E7',
    price: 38, tags: ['seasonal'], sold: false, face: 'wink', seed: true,
    long: 'Morello cherries cooked with kirsch until they collapse, swirled through almond cream with shards of homemade marzipan crumble for crunch.',
    ingredients: ['Organic Jersey cream', 'Morello cherries', 'Marcona almonds', 'Marzipan', 'Egg yolks', 'Kirsch', 'Cane sugar'],
    allergens: ['Mælk', 'Æg', 'Mandel'], churned: 'This morning, 06:55',
  },
  {
    id: 'lic', store: 'algade', name: 'Salted Licorice',
    desc: 'Finnish salmiakki, soft cream, an unmistakable bite.',
    color: 'var(--licorice)', deep: 'var(--licorice-deep)', bg: '#DDD7CB',
    price: 36, tags: ['popular'], sold: false, face: 'tongue', seed: true,
    long: 'Pure Finnish salmiakki powder dissolved into our cream base. You love it or you really don\'t. Either is fine.',
    ingredients: ['Organic Jersey cream', 'Salmiakki', 'Licorice root', 'Egg yolks', 'Cane sugar'],
    allergens: ['Mælk', 'Æg'], churned: 'This morning, 07:20',
  },
  {
    id: 'hazel', store: 'algade', name: 'Hazelnut Praline',
    desc: 'Roasted Piedmont hazelnuts churned into silky cream with caramelised praline shards.',
    color: '#C4956A', deep: '#6E4A22', bg: '#EFE0CC',
    price: 40, tags: ['popular'], sold: false, face: 'cool',
    allergens: ['Mælk', 'Æg', 'Hasselnød'],
  },
  {
    id: 'banana', store: 'algade', name: 'Banana Caramel',
    desc: 'Roasted bananas folded into salted-caramel cream.',
    color: '#F2D880', deep: '#8E6A1E', bg: '#FCF1CF',
    price: 36, tags: ['new'], sold: false, face: 'happy',
    allergens: ['Mælk', 'Æg'],
  },
  {
    id: 'strac', store: 'algade', name: 'Stracciatella',
    desc: 'Cream base shattered with thin ribbons of dark chocolate.',
    color: '#F4ECDC', deep: '#3A2C1E', bg: '#F7EFD7',
    price: 36, tags: ['popular'], sold: false, face: 'happy',
    allergens: ['Mælk', 'Æg'],
  },
  {
    id: 'tira', store: 'algade', name: 'Tiramisu',
    desc: 'Mascarpone cream, espresso-soaked savoiardi, dusted cocoa.',
    color: '#D6B68A', deep: '#5C3E1E', bg: '#EFE0CC',
    price: 40, tags: ['popular'], sold: false, face: 'cool',
    allergens: ['Mælk', 'Æg', 'Hvede', 'Gluten'],
  },
  {
    id: 'pecan', store: 'algade', name: 'Brown Butter Pecan',
    desc: 'Browned butter, toasted pecans, a pinch of flaky salt.',
    color: '#C9A06A', deep: '#5A3E1A', bg: '#F0E2C9',
    price: 40, tags: ['seasonal'], sold: false, face: 'sleepy',
    allergens: ['Mælk', 'Æg', 'Pekannød'],
  },
  {
    id: 'cheese', store: 'algade', name: 'Strawberry Cheesecake',
    desc: 'Tangy cheesecake cream with a ribbon of strawberry compote and graham crumb.',
    color: '#F4C2C8', deep: '#A03A4C', bg: '#FBE0E4',
    price: 38, tags: ['popular'], sold: false, face: 'love',
    allergens: ['Mælk', 'Æg', 'Hvede', 'Gluten'],
  },
  {
    id: 'cinn', store: 'algade', name: 'Cinnamon Roll',
    desc: 'Cream cheese frosting cream, brown-sugar dough chunks, cinnamon swirl.',
    color: '#E0B98A', deep: '#7C4520', bg: '#F2DFC2',
    price: 40, tags: ['new'], sold: false, face: 'wow',
    allergens: ['Mælk', 'Æg', 'Hvede', 'Gluten'],
  },
  {
    id: 'cnc', store: 'algade', name: 'Cookies & Cream',
    desc: 'Sweet cream broken up with crushed chocolate sandwich cookies.',
    color: '#E8DDC7', deep: '#2A2620', bg: '#EFE6CF',
    price: 36, tags: ['popular'], sold: false, face: 'happy',
    allergens: ['Mælk', 'Æg', 'Hvede', 'Gluten', 'Soja'],
  },
  {
    id: 'mint', store: 'algade', name: 'Mint Chocolate Chip',
    desc: 'Fresh-mint-steeped cream, hand-shaved 70% dark chocolate flakes.',
    color: '#BFDDC4', deep: '#2E6E48', bg: '#E2EFE3',
    price: 36, tags: ['popular'], sold: false, face: 'cool',
    allergens: ['Mælk', 'Æg'],
  },
  {
    id: 'coco', store: 'algade', name: 'Coconut Chocolate',
    desc: 'Toasted coconut cream, dark chocolate shards, almond crumble.',
    color: '#F0E5D2', deep: '#3E2A1E', bg: '#F4E9D8',
    price: 38, tags: ['new', 'vegan'], sold: false, face: 'wink',
    allergens: ['Kokos', 'Mandel'],
  },
  {
    id: 'pbf', store: 'algade', name: 'Peanut Butter Fudge',
    desc: 'Salted peanut butter cream with a thick chocolate fudge swirl.',
    color: '#D8B07A', deep: '#5C361A', bg: '#F0DCBE',
    price: 38, tags: ['popular'], sold: false, face: 'tongue',
    allergens: ['Mælk', 'Æg', 'Jordnød'],
  },
  {
    id: 'rocky', store: 'algade', name: 'Rocky Road',
    desc: 'Chocolate cream, marshmallow ribbon, toasted almonds.',
    color: '#9C6E4E', deep: '#3E2418', bg: '#E8D8C6',
    price: 38, tags: ['popular'], sold: false, face: 'wow',
    allergens: ['Mælk', 'Æg', 'Mandel'],
  },
  {
    id: 'maple', store: 'algade', name: 'Maple Walnut',
    desc: 'Real Vermont maple, candied walnuts, a pinch of salt.',
    color: '#D6A86A', deep: '#6E3E1A', bg: '#F0DDBC',
    price: 38, tags: ['seasonal'], sold: false, face: 'sleepy',
    allergens: ['Mælk', 'Æg', 'Valnød'],
  },
  {
    id: 'brulee', store: 'algade', name: 'Crème Brûlée',
    desc: 'Vanilla custard ice cream with a torched caramel sugar crunch.',
    color: '#F2DDA8', deep: '#7E5A1E', bg: '#FAEFCC',
    price: 40, tags: ['popular'], sold: false, face: 'happy',
    allergens: ['Mælk', 'Æg'],
  },
  {
    id: 'cake', store: 'algade', name: 'Birthday Cake',
    desc: 'Buttercake cream, rainbow sprinkles, vanilla frosting swirl.',
    color: '#F8E0E8', deep: '#A04A6E', bg: '#FCE6EE',
    price: 38, tags: ['popular'], sold: false, face: 'wow',
    allergens: ['Mælk', 'Æg', 'Hvede', 'Gluten'],
  },
  {
    id: 'rum', store: 'algade', name: 'Rum Raisin',
    desc: 'Plump raisins soaked in dark rum, folded into vanilla cream.',
    color: '#D8C2A0', deep: '#5C3E1E', bg: '#EEDCC2',
    price: 38, tags: ['vegetarian'], sold: false, face: 'cool',
    allergens: ['Mælk', 'Æg'],
  },

  // ─── Havnens Is (25) ─────────────────────────────────────────────────────
  {
    id: 'blue', store: 'havnens', name: 'Blueberry Skyr',
    desc: 'Roasted Nordic blueberries folded into tangy skyr cream.',
    color: 'var(--blueberry)', deep: 'var(--blueberry-deep)', bg: '#ECEEF7',
    price: 38, tags: ['new', 'seasonal'], sold: false, face: 'happy', seed: true,
    long: 'Wild Nordic blueberries roasted at low heat until they burst, then folded — barely — into Icelandic-style skyr cream. Deep purple ripples; tangy and light.',
    ingredients: ['Skyr', 'Organic cream', 'Wild Nordic blueberries', 'Cane sugar', 'Lemon zest'],
    allergens: ['Mælk'], churned: 'This morning, 06:08',
  },
  {
    id: 'mango', store: 'havnens', name: 'Mango Cardamom',
    desc: 'Alphonso mango sorbet, green cardamom, lime zest.',
    color: 'var(--mango)', deep: 'var(--mango-deep)', bg: '#FBF1DC',
    price: 36, tags: ['vegan', 'sorbet'], sold: false, face: 'wow', seed: true,
    long: 'Alphonso mangoes — flown in once a year — blitzed with freshly cracked green cardamom and a hit of lime.',
    ingredients: ['Alphonso mango purée (70%)', 'Green cardamom', 'Lime', 'Cane sugar'],
    allergens: [], churned: 'This morning, 06:22',
  },
  {
    id: 'rhu', store: 'havnens', name: 'Rhubarb Rose',
    desc: 'Stewed garden rhubarb, a whisper of rosewater.',
    color: 'var(--rhubarb)', deep: 'var(--rhubarb-deep)', bg: '#FCE6E9',
    price: 38, tags: ['seasonal', 'sorbet', 'vegan'], sold: false, face: 'wink', seed: true,
    long: 'Garden rhubarb stewed with sugar and a few drops of rosewater.',
    ingredients: ['Garden rhubarb (60%)', 'Cane sugar', 'Rosewater', 'Lemon juice'],
    allergens: [], churned: 'This morning, 06:32',
  },
  {
    id: 'mat', store: 'havnens', name: 'Matcha White Chocolate',
    desc: 'Ceremonial-grade Uji matcha, milky white chocolate chunks.',
    color: 'var(--matcha)', deep: 'var(--matcha-deep)', bg: '#E9F0E5',
    price: 42, tags: ['new'], sold: false, face: 'sleepy', seed: true,
    long: 'Uji ceremonial matcha sifted into hot cream until it turns electric green, balanced with chunks of Valrhona Ivoire.',
    ingredients: ['Organic cream', 'Uji matcha', 'Valrhona Ivoire', 'Egg yolks', 'Cane sugar'],
    allergens: ['Mælk', 'Æg', 'Soja'], churned: 'This morning, 06:50',
  },
  {
    id: 'peach', store: 'havnens', name: 'Peach Iced Tea',
    desc: 'White peach sorbet steeped with jasmine tea.',
    color: '#F2B89A', deep: '#A85C2A', bg: '#FAE9DC',
    price: 36, tags: ['new', 'sorbet', 'vegan', 'sugarfree'], sold: false, face: 'happy', seed: true,
    long: 'White peaches blended into a chilled jasmine tea steep, sweetened only with monk fruit.',
    ingredients: ['White peaches (65%)', 'Jasmine tea', 'Monk fruit', 'Lemon'],
    allergens: [], churned: 'This morning, 07:10',
  },
  {
    id: 'fig', store: 'havnens', name: 'Black Fig Walnut',
    desc: 'Roasted black figs, candied walnuts, brown butter.',
    color: '#8C5A8A', deep: '#3E2440', bg: '#EADFE8',
    price: 40, tags: ['seasonal'], sold: false, face: 'cool', seed: true,
    long: 'Black Mission figs roasted with honey and a pinch of black pepper, swirled through brown-butter cream studded with candied walnuts.',
    ingredients: ['Jersey cream', 'Brown butter', 'Black Mission figs', 'Candied walnuts', 'Egg yolks', 'Cane sugar'],
    allergens: ['Mælk', 'Æg', 'Valnød'], churned: 'This morning, 07:25',
  },
  {
    id: 'elder', store: 'havnens', name: 'Elderflower Cucumber',
    desc: 'Cold-pressed cucumber, hand-foraged elderflower.',
    color: '#D7E3B8', deep: '#6C7F38', bg: '#F1F4E2',
    price: 36, tags: ['new', 'sorbet', 'vegan', 'sugarfree'], sold: true, face: 'sleepy', seed: true,
    long: 'Cucumbers cold-pressed at dawn, blended with elderflower foraged on the road to Holbæk.',
    ingredients: ['Cold-pressed cucumber', 'Elderflower', 'Monk fruit', 'Lemon', 'Salt'],
    allergens: [], churned: 'Sold out today',
  },
  {
    id: 'tah', store: 'havnens', name: 'Tahini Halva',
    desc: 'Stone-ground sesame paste, shards of pistachio halva.',
    color: '#E8D5A8', deep: '#9A6E2A', bg: '#F6EDD8',
    price: 40, tags: ['new'], sold: false, face: 'tongue', seed: true,
    long: 'Stone-ground white sesame paste folded into honey-sweet cream, broken up with crumbled pistachio halva.',
    ingredients: ['Jersey cream', 'Stone-ground tahini', 'Pistachio halva', 'Honey', 'Egg yolks', 'Cane sugar'],
    allergens: ['Mælk', 'Æg', 'Sesam', 'Pistacie'], churned: 'This morning, 07:38',
  },
  {
    id: 'yuzu', store: 'havnens', name: 'Yuzu Cream',
    desc: 'Japanese yuzu zest, honeyed cream, a pinch of sea salt.',
    color: '#F2E48A', deep: '#7E5C1E', bg: '#FBF3C2',
    price: 42, tags: ['new'], sold: false, face: 'wow',
    allergens: ['Mælk', 'Æg'],
  },
  {
    id: 'sesame', store: 'havnens', name: 'Black Sesame',
    desc: 'Toasted black sesame, toasty cream, faintly bitter and deeply nutty.',
    color: '#7A7066', deep: '#1F1A14', bg: '#D8D2C8',
    price: 40, tags: ['new'], sold: false, face: 'cool',
    allergens: ['Mælk', 'Æg', 'Sesam'],
  },
  {
    id: 'hib', store: 'havnens', name: 'Hibiscus Sorbet',
    desc: 'Tart hibiscus tea sorbet with a hint of lime and ginger.',
    color: '#D85A78', deep: '#7A1E3A', bg: '#FAD8E0',
    price: 36, tags: ['new', 'sorbet', 'vegan'], sold: false, face: 'wink',
    allergens: [],
  },
  {
    id: 'earl', store: 'havnens', name: 'Earl Grey Cream',
    desc: 'Bergamot-scented Earl Grey leaves steeped into Jersey cream.',
    color: '#C9B6A0', deep: '#4E3A26', bg: '#EBDFCC',
    price: 38, tags: ['popular'], sold: false, face: 'sleepy',
    allergens: ['Mælk', 'Æg'],
  },
  {
    id: 'lychee', store: 'havnens', name: 'Lychee Rose',
    desc: 'Lychee sorbet kissed with rosewater and lime.',
    color: '#F8D6DC', deep: '#A04A6E', bg: '#FCE6EC',
    price: 38, tags: ['new', 'sorbet', 'vegan'], sold: false, face: 'love',
    allergens: [],
  },
  {
    id: 'saff', store: 'havnens', name: 'Saffron Pistachio',
    desc: 'Persian saffron-infused cream, crushed pistachios, a thread of honey.',
    color: '#F2C66A', deep: '#8E5C1A', bg: '#FAE6BE',
    price: 44, tags: ['seasonal'], sold: false, face: 'cool',
    allergens: ['Mælk', 'Æg', 'Pistacie'],
  },
  {
    id: 'olive', store: 'havnens', name: 'Olive Oil Lemon',
    desc: 'Cold-pressed Sicilian olive oil, lemon zest, flaky salt.',
    color: '#E4DC9E', deep: '#5E5A1E', bg: '#F2EEC6',
    price: 40, tags: ['new'], sold: false, face: 'happy',
    allergens: ['Mælk', 'Æg'],
  },
  {
    id: 'char', store: 'havnens', name: 'Charcoal Coconut',
    desc: 'Activated charcoal coconut cream — inky black, vegan, vaguely dramatic.',
    color: '#3E3A36', deep: '#0A0805', bg: '#D2CDC6',
    price: 40, tags: ['new', 'vegan'], sold: false, face: 'tongue',
    allergens: ['Kokos'],
  },
  {
    id: 'miso', store: 'havnens', name: 'Miso Caramel',
    desc: 'White miso whipped into salted caramel cream — funky, deep, irresistible.',
    color: '#D8A86A', deep: '#5E3A1A', bg: '#F0DABE',
    price: 42, tags: ['new'], sold: false, face: 'wow',
    allergens: ['Mælk', 'Æg', 'Soja'],
  },
  {
    id: 'beet', store: 'havnens', name: 'Beetroot Vanilla',
    desc: 'Roasted beetroot mellowed by Madagascar vanilla — earthy and electric pink.',
    color: '#D86A8E', deep: '#6E1E40', bg: '#F8D8E2',
    price: 38, tags: ['seasonal'], sold: false, face: 'wink',
    allergens: ['Mælk', 'Æg'],
  },
  {
    id: 'sb', store: 'havnens', name: 'Sea Buckthorn Sorbet',
    desc: 'Wild sea buckthorn berries — sharp, sour, the colour of a setting sun.',
    color: '#F2A04E', deep: '#8E3E0A', bg: '#FAD8B6',
    price: 38, tags: ['new', 'sorbet', 'vegan'], sold: false, face: 'wow',
    allergens: [],
  },
  {
    id: 'birch', store: 'havnens', name: 'Birch Sap Cream',
    desc: 'Spring-tapped birch sap reduced and folded into cream. Tastes like a forest after rain.',
    color: '#E8E2C6', deep: '#5C4A1E', bg: '#F2ECD8',
    price: 40, tags: ['new'], sold: false, face: 'sleepy',
    allergens: ['Mælk', 'Æg'],
  },
  {
    id: 'sloe', store: 'havnens', name: 'Sloe Gin Sorbet',
    desc: 'Hedgerow sloes infused with gin and a twist of orange peel.',
    color: '#7A2A4E', deep: '#3E0F22', bg: '#D8B8C8',
    price: 42, tags: ['seasonal', 'sorbet', 'vegan'], sold: false, face: 'cool',
    allergens: [],
  },
  {
    id: 'cider', store: 'havnens', name: 'Apple Cider Donut',
    desc: 'Spiced cider reduction folded into cream with sugary donut crumbs.',
    color: '#E0B07A', deep: '#6E3E18', bg: '#F2DDC2',
    price: 40, tags: ['seasonal'], sold: false, face: 'happy',
    allergens: ['Mælk', 'Æg', 'Hvede', 'Gluten'],
  },
  {
    id: 'pear', store: 'havnens', name: 'Pear Bay Leaf Sorbet',
    desc: 'Poached pears infused with fresh bay leaf and a squeeze of lemon.',
    color: '#E2D8B0', deep: '#5C4E1E', bg: '#EFE7C6',
    price: 38, tags: ['seasonal', 'sorbet', 'vegan'], sold: false, face: 'sleepy',
    allergens: [],
  },
  {
    id: 'quince', store: 'havnens', name: 'Quince Honey',
    desc: 'Slow-poached quince in honeyed cream — autumn in a scoop.',
    color: '#F0B49A', deep: '#7C3E1A', bg: '#FBD8C2',
    price: 40, tags: ['seasonal'], sold: false, face: 'happy',
    allergens: ['Mælk', 'Æg'],
  },
  {
    id: 'plum', store: 'havnens', name: 'Plum Sake Sorbet',
    desc: 'Umeshu-soaked Japanese plums, churned to a deep ruby sorbet.',
    color: '#A0364E', deep: '#4E0F22', bg: '#E8C8D2',
    price: 42, tags: ['new', 'sorbet'], sold: false, face: 'wow',
    allergens: [],
  },
];

const TAG_META = {
  popular:    { label: 'Populær',    cls: 'badge-popular' },
  new:        { label: 'Ny',          cls: 'badge-new' },
  vegan:      { label: 'Vegansk',     cls: 'badge-vegan' },
  seasonal:   { label: 'Sæson',       cls: 'badge-seasonal' },
  sugarfree:  { label: 'Sukkerfri',   cls: 'badge-sugarfree' },
  sorbet:     { label: 'Sorbet',      cls: 'badge-sorbet' },
  vegetarian: { label: 'Vegetarisk',  cls: 'badge-vegan' },
};

const FILTERS = [
  { key: 'all',       label: 'Alt' },
  { key: 'popular',   label: 'Populær' },
  { key: 'new',       label: 'Ny' },
  { key: 'seasonal',  label: 'Sæson' },
  { key: 'vegan',     label: 'Vegansk' },
  { key: 'sorbet',    label: 'Sorbet' },
  { key: 'sugarfree', label: 'Sukkerfri' },
];

const STORES = [
  { key: 'algade',  name: 'Algade Is',  sub: 'Bymidten' },
  { key: 'havnens', name: 'Havnens Is', sub: 'Havnen' },
];

window.TAG_META = TAG_META;
window.FILTERS = FILTERS;
window.STORES = STORES;
// NOTE: window.FLAVORS is intentionally NOT set here. The public pages poll for
// window.FLAVORS before their single render, so we delay setting it until after
// we've hydrated localStorage from Cloudflare KV (see the bottom of this file).

/* ─────────── Catalog override layer ───────────
   Persisted edits, additions, and deletions made via the admin live in
   localStorage under 'rs_catalog'. Both the admin and the public shop
   read through getLiveCatalog() so the two stay in sync. */

const ALLERGEN_OPTIONS = [
  'Mælk', 'Æg', 'Hvede', 'Gluten', 'Soja', 'Jordnød',
  'Mandel', 'Hasselnød', 'Valnød', 'Pekannød', 'Pistacie',
  'Sesam', 'Kokos',
];

const FACE_OPTIONS = [
  { key: 'happy',  label: 'Glad' },
  { key: 'wink',   label: 'Blink' },
  { key: 'cool',   label: 'Cool' },
  { key: 'love',   label: 'Hjerteøjne' },
  { key: 'tongue', label: 'Tunge ude' },
  { key: 'sleepy', label: 'Søvnig' },
  { key: 'wow',    label: 'Wow' },
];

function loadCatalogOverrides() {
  try {
    const raw = localStorage.getItem('rs_catalog');
    if (raw) {
      const p = JSON.parse(raw);
      return {
        added: p.added || [],
        edited: p.edited || {},
        deleted: p.deleted || [],
        order: p.order || { algade: [], havnens: [] },
      };
    }
  } catch (_) {}
  return { added: [], edited: {}, deleted: [], order: { algade: [], havnens: [] } };
}

function saveCatalogOverrides(o) {
  localStorage.setItem('rs_catalog', JSON.stringify(o));
  // notify same-tab listeners (storage event only fires cross-tab)
  window.dispatchEvent(new CustomEvent('catalogchange'));
}

function getLiveCatalog() {
  const ov = loadCatalogOverrides();
  const delSet = new Set(ov.deleted);
  const base = FLAVORS
    .filter(f => !delSet.has(f.id))
    .map(f => ov.edited[f.id] ? { ...f, ...ov.edited[f.id] } : f);
  const all = [...base, ...ov.added];

  // Apply per-store ordering: known IDs first in the saved order, then any
  // remaining flavors in their natural order. Flavors from other stores keep
  // their position relative to each other.
  const order = ov.order || {};
  const byStore = {};
  all.forEach(f => { (byStore[f.store] = byStore[f.store] || []).push(f); });
  Object.keys(byStore).forEach(storeKey => {
    const saved = order[storeKey] || [];
    const ix = new Map(saved.map((id, i) => [id, i]));
    byStore[storeKey].sort((a, b) => {
      const ai = ix.has(a.id) ? ix.get(a.id) : Infinity;
      const bi = ix.has(b.id) ? ix.get(b.id) : Infinity;
      return ai - bi;
    });
  });
  // Re-interleave in original store-grouping (algade then havnens then any extras)
  const seenStores = new Set();
  const out = [];
  all.forEach(f => {
    if (seenStores.has(f.store)) return;
    seenStores.add(f.store);
    out.push(...byStore[f.store]);
  });
  return out;
}

window.ALLERGEN_OPTIONS = ALLERGEN_OPTIONS;
window.FACE_OPTIONS = FACE_OPTIONS;
window.loadCatalogOverrides = loadCatalogOverrides;
window.saveCatalogOverrides = saveCatalogOverrides;
window.getLiveCatalog = getLiveCatalog;

/* ─────────── Cloudflare KV hydration ───────────
   The editable flavor data lives in KV: GET /api/flavors (today's picks,
   localStorage 'rs_daily_picks') and GET /api/catalog (catalog overrides,
   localStorage 'rs_catalog'). We fetch both into localStorage, THEN expose
   window.FLAVORS — which is the flag every public page waits on before it
   renders — so the first (and only) render already reflects the server state.
   Falls back to whatever is in localStorage / the built-in seed when offline. */
(function hydrateFromKV() {
  function pull(url, lsKey, validate) {
    return fetch(url, { cache: 'no-store' })
      .then(function (r) { return r.ok ? r.json() : null; })
      .then(function (data) {
        if (data && validate(data)) {
          try { localStorage.setItem(lsKey, JSON.stringify(data)); } catch (e) {}
        }
      })
      .catch(function () { /* offline → keep local/seed */ });
  }

  function finish() {
    window.FLAVORS = FLAVORS;            // unblock the page renderers
    // Nudge any live (React) listeners — flavors-app on dagensis.html.
    try { window.dispatchEvent(new StorageEvent('storage', { key: 'rs_daily_picks' })); } catch (e) {}
    window.dispatchEvent(new CustomEvent('catalogchange'));
  }

  Promise.all([
    pull('/api/catalog', 'rs_catalog', function (d) { return d && typeof d === 'object'; }),
    pull('/api/flavors', 'rs_daily_picks', function (d) { return d && typeof d === 'object'; }),
  ]).then(finish, finish);
})();
