// Datos seed + i18n + iconos para KomprApp
// Todo en window.* para compartir entre <script> de Babel.

const I18N = {
  es: {
    appName: 'KomprApp',
    tabs: { list: 'Lista', shop: 'Compra', history: 'Historial', lists: 'Listas', settings: 'Ajustes' },
    pending: 'pendientes',
    pending_one: 'pendiente',
    bought: 'comprados',
    bought_one: 'comprado',
    addPlaceholder: 'Añadir producto…',
    addHint: 'Pulsa enter o di "leche"',
    bulkPasteTitle: 'Varios productos detectados',
    bulkPasteQuestion: 'Se han detectado {n} productos en el portapapeles. ¿Cómo quieres añadirlos?',
    bulkPasteAdd: 'Añadir {n} productos',
    bulkPasteKeepOne: 'Mantener como 1',
    qty: 'Cantidad',
    voiceHint: 'Mantén pulsado para dictar',
    voiceListening: 'Escuchando…',
    listening: 'Escuchando',
    quickAdd: 'Frecuentes',
    empty: 'Lista vacía',
    emptySub: 'Añade el primero abajo ↓',
    emptyShop: 'Nada que comprar',
    emptyShopSub: 'Vuelve a la lista para añadir',
    emptyHistory: 'Sin actividad',
    emptyHistorySub: 'Las acciones aparecerán aquí',
    clearBought: 'Limpiar comprados',
    startShopping: 'Empezar compra',
    finishShopping: 'Terminar',
    progress: 'Progreso',
    nope: 'Cancelar',
    yes: 'Sí',
    deleteQ: '¿Borrar este producto?',
    save: 'Guardar',
    edit: 'Editar',
    delete: 'Eliminar',
    rename: 'Renombrar',
    leave: 'Salir',
    newList: 'Nueva lista',
    listName: 'Nombre de la lista',
    create: 'Crear',
    join: 'Unirme con enlace',
    joinPaste: 'Pega el enlace o el código',
    share: 'Compartir',
    copyLink: 'Copiar enlace',
    copied: '¡Copiado!',
    shareNote: 'Cualquiera con este enlace puede ver y editar',
    account: 'Cuenta',
    signIn: 'Entrar con Google',
    signInWithGoogle: 'Continuar con Google',
    signInWithApple: 'Continuar con Apple',
    signOut: 'Cerrar sesión',
    guestNote: 'Modo invitado · datos solo en este dispositivo',
    deleteAccount: 'Borrar cuenta y datos',
    deleteAccountTitle: '¿Borrar tu cuenta?',
    deleteAccountWarn: 'Se borrarán todas tus listas, productos e historial. Esta acción es irreversible.',
    deleteAccountConfirmHint: 'Escribe BORRAR para confirmar',
    deleteAccountConfirmWord: 'BORRAR',
    deleteAccountCta: 'Borrar definitivamente',
    deleteAccountCancel: 'Cancelar',
    deleteAccountSuccess: 'Cuenta borrada',
    deleteAccountError: 'No se pudo borrar la cuenta. Inténtalo de nuevo o escribe a soporte.',
    appearance: 'Apariencia',
    light: 'Claro',
    dark: 'Oscuro',
    auto: 'Auto',
    preferences: 'Preferencias',
    autoCategory: 'Categorización automática',
    about: 'Acerca de',
    today: 'hoy',
    yesterday: 'ayer',
    daysAgo: 'hace {n}d',
    actions: {
      added: 'añadió', purchased: 'compró', unpurchased: 'desmarcó',
      deleted: 'borró', edited: 'editó', archived: 'archivó',
    },
    grouped: {
      added: 'añadidos', purchased: 'comprados', deleted: 'borrados',
      edited: 'editados', archived: 'archivados',
    },
    items: 'productos',
    item_one: 'producto',
    showMore: 'Ver todo',
    today_full: 'Hoy',
    yesterday_full: 'Ayer',
    earlier: 'Antes',
    sort: {
      title: 'Ordenar',
      byAdded: 'Por fecha (recientes primero)',
      byName: 'Alfabético',
      groupByCategory: 'Agrupar por categoría',
    },
    deletedToast: 'Eliminado “{name}”',
    undo: 'Deshacer',
    cats: {
      'aceites':       'Aceite, especias y salsas',
      'aguarefrescos': 'Agua y refrescos',
      'aperitivos':    'Aperitivos',
      'arrozpasta':    'Arroz, legumbres y pasta',
      'dulces':        'Azúcar, caramelos y chocolate',
      'bebe':          'Bebé',
      'bodega':        'Bodega',
      'cafe':          'Cacao, café e infusiones',
      'carne':         'Carne',
      'cereales':      'Cereales y galletas',
      'charcuteria':   'Charcutería y quesos',
      'congelados':    'Congelados',
      'conservas':     'Conservas, caldos y cremas',
      'cabello':       'Cuidado del cabello',
      'cuidadofacial': 'Cuidado facial y corporal',
      'parafarmacia':  'Fitoterapia y parafarmacia',
      'frutaverdura':  'Fruta y verdura',
      'lacteos':       'Huevos, leche y mantequilla',
      'limpieza':      'Limpieza y hogar',
      'maquillaje':    'Maquillaje',
      'pescado':       'Marisco y pescado',
      'mascotas':      'Mascotas',
      'panaderia':     'Panadería y pastelería',
      'preparados':    'Pizzas y platos preparados',
      'postres':       'Postres y yogures',
      'zumos':         'Zumos',
      'otros':         'Otros',
    },
  },
  en: {
    appName: 'KomprApp',
    tabs: { list: 'List', shop: 'Shop', history: 'History', lists: 'Lists', settings: 'Settings' },
    pending: 'to buy',
    pending_one: 'to buy',
    bought: 'bought',
    bought_one: 'bought',
    addPlaceholder: 'Add item…',
    addHint: 'Hit enter or say "milk"',
    bulkPasteTitle: 'Multiple items detected',
    bulkPasteQuestion: '{n} items detected in the clipboard. How do you want to add them?',
    bulkPasteAdd: 'Add {n} items',
    bulkPasteKeepOne: 'Keep as 1',
    qty: 'Qty',
    voiceHint: 'Hold to dictate',
    voiceListening: 'Listening…',
    listening: 'Listening',
    quickAdd: 'Frequent',
    empty: 'Empty list',
    emptySub: 'Add your first one below ↓',
    emptyShop: 'Nothing to shop',
    emptyShopSub: 'Go back to the list to add',
    emptyHistory: 'No activity',
    emptyHistorySub: 'Actions will show up here',
    clearBought: 'Clear bought',
    startShopping: 'Start shopping',
    finishShopping: 'Finish',
    progress: 'Progress',
    nope: 'Cancel',
    yes: 'Yes',
    deleteQ: 'Delete this item?',
    save: 'Save',
    edit: 'Edit',
    delete: 'Delete',
    rename: 'Rename',
    leave: 'Leave',
    newList: 'New list',
    listName: 'List name',
    create: 'Create',
    join: 'Join with link',
    joinPaste: 'Paste link or code',
    share: 'Share',
    copyLink: 'Copy link',
    copied: 'Copied!',
    shareNote: 'Anyone with this link can view and edit',
    account: 'Account',
    signIn: 'Sign in with Google',
    signInWithGoogle: 'Continue with Google',
    signInWithApple: 'Continue with Apple',
    signOut: 'Sign out',
    guestNote: 'Guest mode · data lives only on this device',
    deleteAccount: 'Delete account and data',
    deleteAccountTitle: 'Delete your account?',
    deleteAccountWarn: 'All your lists, items and history will be deleted. This cannot be undone.',
    deleteAccountConfirmHint: 'Type DELETE to confirm',
    deleteAccountConfirmWord: 'DELETE',
    deleteAccountCta: 'Delete permanently',
    deleteAccountCancel: 'Cancel',
    deleteAccountSuccess: 'Account deleted',
    deleteAccountError: 'Could not delete the account. Try again or contact support.',
    appearance: 'Appearance',
    light: 'Light',
    dark: 'Dark',
    auto: 'Auto',
    preferences: 'Preferences',
    autoCategory: 'Auto categorize',
    about: 'About',
    today: 'today',
    yesterday: 'yesterday',
    daysAgo: '{n}d ago',
    actions: {
      added: 'added', purchased: 'bought', unpurchased: 'unmarked',
      deleted: 'deleted', edited: 'edited', archived: 'archived',
    },
    grouped: {
      added: 'added', purchased: 'bought', deleted: 'deleted',
      edited: 'edited', archived: 'archived',
    },
    items: 'items',
    item_one: 'item',
    showMore: 'Show all',
    today_full: 'Today',
    yesterday_full: 'Yesterday',
    earlier: 'Earlier',
    sort: {
      title: 'Sort',
      byAdded: 'By date (newest first)',
      byName: 'Alphabetical',
      groupByCategory: 'Group by category',
    },
    deletedToast: 'Deleted “{name}”',
    undo: 'Undo',
    cats: {
      'aceites':       'Oils, spices & sauces',
      'aguarefrescos': 'Water & soft drinks',
      'aperitivos':    'Snacks',
      'arrozpasta':    'Rice, beans & pasta',
      'dulces':        'Sugar, candy & chocolate',
      'bebe':          'Baby',
      'bodega':        'Liquor',
      'cafe':          'Cocoa, coffee & tea',
      'carne':         'Meat',
      'cereales':      'Cereal & cookies',
      'charcuteria':   'Deli & cheese',
      'congelados':    'Frozen',
      'conservas':     'Canned & broths',
      'cabello':       'Hair care',
      'cuidadofacial': 'Face & body care',
      'parafarmacia':  'Pharmacy',
      'frutaverdura':  'Fruit & vegetables',
      'lacteos':       'Eggs, milk & butter',
      'limpieza':      'Cleaning & home',
      'maquillaje':    'Makeup',
      'pescado':       'Fish & seafood',
      'mascotas':      'Pets',
      'panaderia':     'Bakery',
      'preparados':    'Pizza & ready meals',
      'postres':       'Desserts & yogurts',
      'zumos':         'Juices',
      'otros':         'Other',
    },
  },
};

const CATEGORIES = {
  'aceites':       { emoji: '🫒', glyph: 'cat-oil' },
  'aguarefrescos': { emoji: '🥤', glyph: 'cat-soda' },
  'aperitivos':    { emoji: '🍿', glyph: 'cat-snack' },
  'arrozpasta':    { emoji: '🍚', glyph: 'cat-rice' },
  'dulces':        { emoji: '🍬', glyph: 'cat-candy' },
  'bebe':          { emoji: '🍼', glyph: 'cat-baby' },
  'bodega':        { emoji: '🍷', glyph: 'cat-wine' },
  'cafe':          { emoji: '☕', glyph: 'cat-coffee' },
  'carne':         { emoji: '🥩', glyph: 'cat-meat' },
  'cereales':      { emoji: '🥣', glyph: 'cat-cereal' },
  'charcuteria':   { emoji: '🧀', glyph: 'cat-cheese' },
  'congelados':    { emoji: '🧊', glyph: 'cat-ice' },
  'conservas':     { emoji: '🥫', glyph: 'cat-can' },
  'cabello':       { emoji: '💇', glyph: 'cat-hair' },
  'cuidadofacial': { emoji: '🧴', glyph: 'cat-lotion' },
  'parafarmacia':  { emoji: '💊', glyph: 'cat-pill' },
  'frutaverdura':  { emoji: '🥬', glyph: 'cat-leaf' },
  'lacteos':       { emoji: '🥛', glyph: 'cat-milk' },
  'limpieza':      { emoji: '🧽', glyph: 'cat-broom' },
  'maquillaje':    { emoji: '💄', glyph: 'cat-lipstick' },
  'pescado':       { emoji: '🐟', glyph: 'cat-fish' },
  'mascotas':      { emoji: '🐾', glyph: 'cat-paw' },
  'panaderia':     { emoji: '🥖', glyph: 'cat-bread' },
  'preparados':    { emoji: '🍕', glyph: 'cat-pizza' },
  'postres':       { emoji: '🍮', glyph: 'cat-flan' },
  'zumos':         { emoji: '🧃', glyph: 'cat-juice' },
  'otros':         { emoji: '📦', glyph: 'cat-box' },
  // Aliases legacy: items creados antes del rediseño de categorías. Apuntan
  // a la categoría nueva más cercana para que los iconos sigan resolviendo.
  'frutas':        { emoji: '🥬', glyph: 'cat-leaf',   alias: 'frutaverdura' },
  'despensa':      { emoji: '🥫', glyph: 'cat-can',    alias: 'conservas' },
  'bebidas':       { emoji: '🥤', glyph: 'cat-soda',   alias: 'aguarefrescos' },
  'higiene':       { emoji: '🧴', glyph: 'cat-lotion', alias: 'cuidadofacial' },
};

// Mapas para los distintos estilos de icono que el usuario puede elegir
// en Ajustes. La clave es `glyph` de CATEGORIES.

// Material Symbols (Outlined) — nombres de la fuente de iconos de Google.
const MATERIAL_NAMES = {
  'cat-oil':       'water_drop',
  'cat-soda':      'local_drink',
  'cat-snack':     'cookie',
  'cat-rice':      'rice_bowl',
  'cat-candy':     'icecream',
  'cat-baby':      'child_friendly',
  'cat-wine':      'wine_bar',
  'cat-coffee':    'local_cafe',
  'cat-meat':      'kebab_dining',
  'cat-cereal':    'breakfast_dining',
  'cat-cheese':    'lunch_dining',
  'cat-ice':       'ac_unit',
  'cat-can':       'kitchen',
  'cat-hair':      'content_cut',
  'cat-lotion':    'spa',
  'cat-pill':      'medication',
  'cat-leaf':      'eco',
  'cat-milk':      'egg_alt',
  'cat-broom':     'cleaning_services',
  'cat-lipstick':  'face_retouching_natural',
  'cat-fish':      'set_meal',
  'cat-paw':       'pets',
  'cat-bread':     'bakery_dining',
  'cat-pizza':     'local_pizza',
  'cat-flan':      'cake',
  'cat-juice':     'liquor',
  'cat-box':       'inventory_2',
};

// OpenMoji — código unicode hex del emoji. Renderiza como <img> desde CDN.
const OPENMOJI_CODES = {
  'cat-oil':       '1FAD2',
  'cat-soda':      '1F964',
  'cat-snack':     '1F37F',
  'cat-rice':      '1F35A',
  'cat-candy':     '1F36C',
  'cat-baby':      '1F37C',
  'cat-wine':      '1F377',
  'cat-coffee':    '2615',
  'cat-meat':      '1F969',
  'cat-cereal':    '1F963',
  'cat-cheese':    '1F9C0',
  'cat-ice':       '1F9CA',
  'cat-can':       '1F96B',
  'cat-hair':      '1F487',
  'cat-lotion':    '1F9F4',
  'cat-pill':      '1F48A',
  'cat-leaf':      '1F96C',
  'cat-milk':      '1F95B',
  'cat-broom':     '1F9F9',
  'cat-lipstick':  '1F484',
  'cat-fish':      '1F41F',
  'cat-paw':       '1F43E',
  'cat-bread':     '1F956',
  'cat-pizza':     '1F355',
  'cat-flan':      '1F36E',
  'cat-juice':     '1F9C3',
  'cat-box':       '1F4E6',
};

// Helper: renderiza el icono de una categoría según el estilo seleccionado
// por el usuario (`window.__iconStyle`, sincronizado desde useAppState).
// Estilos soportados: 'emoji' | 'line' | 'material' | 'openmoji'.
const CatGlyph = ({ cat, size = 18, stroke = 2.2, style: extraStyle, ...rest }) => {
  const c = typeof cat === 'string' ? CATEGORIES[cat] : cat;
  if (!c) return null;
  const mode = (typeof window !== 'undefined' && window.__iconStyle) || 'material';
  const glyphName = c.glyph || 'cat-box';

  if (mode === 'line') {
    return <Icon name={glyphName} size={size} stroke={stroke} style={extraStyle} {...rest} />;
  }
  if (mode === 'material') {
    return (
      <span className="material-symbols-outlined" aria-hidden="true"
        style={{
          fontSize: size + 4, lineHeight: 1,
          fontVariationSettings: '"FILL" 0, "wght" 400, "GRAD" 0, "opsz" 24',
          ...extraStyle,
        }} {...rest}>
        {MATERIAL_NAMES[glyphName] || 'inventory_2'}
      </span>
    );
  }
  if (mode === 'openmoji') {
    const code = OPENMOJI_CODES[glyphName] || '1F4E6';
    return (
      <img alt="" aria-hidden="true"
        src={`https://cdn.jsdelivr.net/npm/openmoji@15.1.0/color/svg/${code}.svg`}
        width={size + 4} height={size + 4}
        style={{ display: 'inline-block', verticalAlign: 'middle', ...extraStyle }}
        {...rest} />
    );
  }
  // emoji (default): emoji nativo del SO.
  return (
    <span aria-hidden="true"
      style={{ fontSize: size + 4, lineHeight: 1, ...extraStyle }} {...rest}>
      {c.emoji}
    </span>
  );
};

// Reglas de auto-categorización. El matcher normaliza acentos antes de
// comparar, así que aquí escribimos las keywords ya sin acentos. El orden
// importa: la primera regla que matchee gana, así que las más específicas
// (preparados, charcuteria, mascotas...) van antes de las genéricas
// (frutaverdura, conservas, etc).
const AUTO_RULES = [
  { cat: 'bebe', kw: [
    'bebe','panal','panales','dodot','potito','potitos','papilla','papillas',
    'tetina','tetinas','biberon','biberones','chupete','chupetes','toallitas bebe',
    'leche infantil','leche bebe','nestle bebe','blevit','hero baby','hero baby',
  ]},
  { cat: 'mascotas', kw: [
    'perro','gato','pienso','arena gato','arenero','correa','collar','snack perro',
    'snack gato','royal canin','whiskas','sheba','friskies','purina','dentastix',
    'mascotas','mascota','heno','conejo perro','jaula','acuario','peces tropicales',
  ]},
  { cat: 'parafarmacia', kw: [
    'paracetamol','ibuprofeno','aspirina','enantyum','frenadol','nolotil',
    'omeprazol','vitamina','vitaminas','suplemento','suplementos','tirita','tiritas',
    'venda','vendas','algodon','alcohol','betadine','agua oxigenada','jarabe',
    'jarabes','colirio','isdin','farmacia','parafarmacia','homeopatia',
    'fitoterapia','manzanilla saco','probiotico','melatonina','colageno',
  ]},
  { cat: 'maquillaje', kw: [
    'maquillaje','rimel','mascara pestanas','base maquillaje','corrector',
    'colorete','sombra','sombras','pintalabios','labial','labiales','eyeliner',
    'delineador','brocha','brochas','esmalte','esmaltes','lacanail','lapiz ojos',
    'lapiz labios','primer','iluminador','bronceador','polvos compactos',
    'rubor','sephora','maybelline','loreal',
  ]},
  { cat: 'cabello', kw: [
    'champu','champus','acondicionador','mascarilla pelo','mascarilla cabello',
    'tinte','tintes','laca','espuma pelo','gomina','cera pelo','cepillo pelo',
    'peine','peines','secador','plancha pelo','rulos','horquilla','horquillas',
    'cabello','aceite pelo','keratina','garnier','pantene','herbal essences',
    'tresemme','schwarzkopf','dove pelo',
  ]},
  { cat: 'cuidadofacial', kw: [
    'pasta dental','pasta de dientes','dentifrico','dentifricos','colgate','oral-b','oral b',
    'cepillo dientes','cepillo de dientes','seda dental','enjuague bucal','elmex',
    'tampax','compresa','compresas','tampon','tampones','toallita','toallitas',
    'salvaslip','salvaslips','protege slip',
    'crema facial','crema cara','crema corporal','crema cuerpo','locion','lociones',
    'tonico','serum','contorno ojos','desmaquillante','agua micelar','exfoliante',
    'mascarilla facial','protector solar','solar','spf','aftershave','colonia',
    'colonias','perfume','perfumes','desodorante','desodorantes','jabon','jabones',
    'gel ducha','gel bano','manteca','hidratante','nivea','dove','sanex',
    'lactovit','neutrogena','isdin facial','cremas',
  ]},
  { cat: 'limpieza', kw: [
    'detergente','suavizante','lejia','amoniaco','bayeta','bayetas','esponja',
    'esponjas','fregona','fregonas','escoba','escobas','recogedor','recogedores',
    'cubo','cepillo casa','guantes goma','papel cocina','rollo cocina','servilleta',
    'servilletas','panuelo','panuelos','clinex','kleenex','wc','higienico',
    'higienicos','bolsa basura','bolsas basura','basura','lavavajillas','quitamanchas',
    'limpiahogar','multiusos','cristal','vidrio','limpiacristales','limpiador',
    'limpiadores','ambientador','ambientadores','insecticida','repelente',
    'mistol','fairy','wipp','ariel','colon','don limpio','asevi','pronto',
    'kh-7','vanish','calgonit','finish','papel higienico',
  ]},
  { cat: 'preparados', kw: [
    'pizza','pizzas','lasagna','lasana','lasagnas','canelones','canelone',
    'plato preparado','platos preparados','precocinado','precocinados',
    'empanada','empanadas','empanadilla','empanadillas','croqueta','croquetas',
    'fingers','nuggets','san jacobo','san jacobos','flamenquin','flamenquines',
    'sushi','tabbule','tabule','ensaladilla preparada','wok','noodles',
    'preparada','preparadas','heura','tortilla preparada',
  ]},
  { cat: 'congelados', kw: [
    'congelado','congelados','congelar','helado','helados','sorbete','sorbetes',
    'polo','polos','cubitos','hielo','hielos','guisantes congelados','espinaca congelada',
    'verduras congeladas','pescado congelado','calamares congelados','gambas congeladas',
    'patatas congeladas','frigo','magnum','la menorquina','findus',
  ]},
  { cat: 'pescado', kw: [
    'pescado','pescados','salmon','atun','merluza','bacalao','dorada','lubina',
    'sardina','sardinas','boqueron','boquerones','anchoa','anchoas','caballa',
    'trucha','truchas','gamba','gambas','langostino','langostinos','mejillon',
    'mejillones','almeja','almejas','calamar','calamares','pulpo','pulpos','sepia',
    'sepias','cangrejo','cangrejos','langosta','langostas','rape','mero',
    'mariscos','marisco','surimi','palitos cangrejo','centollo','nécora','navajas',
    'cigala','cigalas',
  ]},
  { cat: 'charcuteria', kw: [
    'jamon','jamones','jamon serrano','jamon iberico','jamon york','york',
    'chorizo','chorizos','salchichon','salchichones','morcilla','morcillas',
    'lomo embuchado','fuet','butifarra','butifarras','salami','salamis','mortadela',
    'mortadelas','bacon','panceta','sobrasada','queso','quesos','manchego','burgos',
    'mozzarella','parmesano','gouda','edam','emmental','provolone','brie','camembert',
    'requeson','ricotta','mascarpone','feta','cheddar','cabra','rulo cabra',
    'tetilla','idiazabal','queso fresco','tranchete','tranchetes','queso loncha',
  ]},
  { cat: 'carne', kw: [
    'carne','carnes','pollo','pollos','pechuga','pechugas','muslo','muslos',
    'contramuslo','contramuslos','ternera','vaca','buey','cerdo','cordero',
    'cabrito','pavo','pavos','conejo','conejos','solomillo','costilla','costillas',
    'chuleta','chuletas','filete','filetes','hamburguesa','hamburguesas','albondiga',
    'albondigas','cocido','redondo','escalope','escalopes','picada','picado','carrillada',
    'rabo toro','secreto','presa iberica','aguja',
  ]},
  { cat: 'lacteos', kw: [
    'leche','leches','desnatada','semidesnatada','entera','huevo','huevos',
    'mantequilla','mantequillas','margarina','margarinas','nata','crema','kefir',
    'mantequilla salada','mantequilla sin sal','huevos camperos','huevos ecologicos',
  ]},
  { cat: 'postres', kw: [
    'yogur','yogures','yogurt','natillas','flan','flanes','mousse','postre','postres',
    'petit suisse','actimel','danone','danacol','bifidus','arroz con leche',
    'cuajada','tarta queso','tarta','cheesecake','tiramisu','panna cotta','gelatina',
  ]},
  { cat: 'cafe', kw: [
    'cafe','cafes','capsula','capsulas','dolce gusto','nespresso','molido','grano',
    'granos','descafeinado','soluble','nescafe','marcilla','saimaza',
    'cacao','colacao','nesquik','choco krispies','infusion','infusiones','manzanilla',
    'poleo','menta','tila','valeriana','rooibos','te','te verde','te negro','te rojo',
    'lipton','hornimans','pompadour','susaron',
  ]},
  { cat: 'aguarefrescos', kw: [
    'agua','aguas','agua mineral','aquarel','bezoya','solan','font vella','lanjaron',
    'refresco','refrescos','coca cola','cocacola','coke','pepsi','fanta','sprite',
    'nestea','aquarius','gatorade','red bull','monster','tonica','tonicas','bitter',
    'soda','schweppes','kas','la casera','seven up','ginger ale',
  ]},
  { cat: 'zumos', kw: [
    'zumo','zumos','jugo','jugos','naranjada','limonada','don simon','granini',
    'minute maid','disfruta','exprimido','smoothie','smoothies','batido','batidos',
  ]},
  { cat: 'bodega', kw: [
    'cerveza','cervezas','vino','vinos','tinto','blanco','rosado','cava','champan',
    'sidra','vermut','vermouth','ron','whisky','whiskey','ginebra','gin','vodka',
    'licor','licores','tequila','aguardiente','jerez','manzanilla vino','cointreau',
    'baileys','jagermeister','mahou','heineken','estrella','san miguel','damm',
    'amstel','beefeater','seagram','beefeater',
  ]},
  { cat: 'aperitivos', kw: [
    'patatas fritas','patata frita','chips','lays','pringles','ruffles','doritos',
    'tortitas','palomitas','popcorn','aceitunas','olivas','encurtido','encurtidos',
    'frutos secos','almendras','nueces','pistachos','anacardos','cacahuetes',
    'pipas','kikos','panchitos','aperitivo','aperitivos','snack','snacks','gusanitos',
    'cheetos','3d','jamon serrano snack',
  ]},
  { cat: 'dulces', kw: [
    'azucar','azucares','azucar moreno','sacarina','stevia','edulcorante',
    'caramelo','caramelos','chuche','chuches','chucherias','gominola','gominolas',
    'haribo','sugus','fini','pez','chicle','chicles','trident','orbit',
    'chocolate','chocolates','bombon','bombones','tableta chocolate','nutella',
    'nocilla','crema cacao','kinder','kit kat','milka','toblerone','snickers',
    'mars','twix','bounty','m&m','lacasitos','lacasa','huesitos',
    'phoskitos','tigreton','bollycao','donut',
  ]},
  { cat: 'cereales', kw: [
    'cereales','cereal','muesli','granola','copos avena','copos','avena',
    'kelloggs','corn flakes','choco krispies','frosties','special k','fitness',
    'all bran','weetabix','galleta','galletas','dorada','marbu','principe','oreo',
    'digestive','maria','maria oro','tosta rica','dinosaurus','chips ahoy',
    'cookie','cookies','barrita cereales','barritas',
  ]},
  { cat: 'panaderia', kw: [
    'pan','panes','barra','barras','baguette','hogaza','hogazas','bollo','bollos',
    'pan integral','pan molde','pan rallado','pan tostado','tostada','tostadas',
    'tosta','tostas','biscote','biscotes','pita','pitas','chapata','chapatas',
    'focaccia','ciabatta','muffin','muffins','croissant','croissants','medialuna',
    'medialunas','napolitana','napolitanas','donut casero','magdalena','magdalenas',
    'bizcocho','bizcochos','brioche','panaderia','pasteleria','pastel','pasteles',
    'tarta panaderia','palmera','palmeras','polvoron','polvorones','mantecado',
    'mantecados','churro','churros','cruasan','tortilla mexicana','wrap','wraps',
    'pan hamburguesa','pan hot dog',
  ]},
  { cat: 'arrozpasta', kw: [
    'arroz','arroces','basmati','jazmin','bomba','integral arroz','pasta','pastas',
    'macarrones','espagueti','espaguetis','spaghetti','penne','fideos','fideo',
    'lasana laminas','laminas lasana','tallarines','tagliatelle','ravioli','tortellini',
    'noodles','ramen','cuscus','quinoa','bulgur','lentejas','garbanzos','judias','alubias',
    'soja','frijol','frijoles','legumbre','legumbres',
  ]},
  { cat: 'aceites', kw: [
    'aceite','aceites','aceite oliva','oliva','virgen extra','aove','girasol','semillas',
    'sesamo','coco aceite','vinagre','vinagres','sal','sales','pimienta','especias',
    'especia','curry','comino','oregano','laurel','tomillo','romero','perejil','cilantro',
    'albahaca','azafran','pimenton','jengibre','canela','clavo','nuez moscada','salsa',
    'salsas','ketchup','mostaza','mayonesa','tabasco','soja salsa','sriracha','barbacoa',
    'bbq','tomate frito','tomate triturado','sofrito','pesto','wasabi','curry pasta',
    'caldo concentrado',
  ]},
  { cat: 'conservas', kw: [
    'conserva','conservas','lata','latas','atun lata','sardinas lata','mejillones lata',
    'berberechos','navajas lata','aceitunas lata','maiz lata','garbanzos cocidos',
    'lentejas cocidas','alubias cocidas','tomate lata','tomate triturado lata',
    'caldo','caldos','crema verduras','crema calabaza','crema bote','sopa','sopas',
    'gazpacho','salmorejo','crema bote','foie','pate','pates','mermelada','mermeladas',
    'miel','frutos secos lata','melocoton almibar','pina almibar',
  ]},
  { cat: 'frutaverdura', kw: [
    'manzana','manzanas','pera','peras','platano','platanos','banana','bananas',
    'naranja','naranjas','limon','limones','lima','limas','mandarina','mandarinas',
    'fresa','fresas','uva','uvas','melon','melones','sandia','sandias','kiwi','kiwis',
    'mango','mangos','papaya','papayas','pina','pinas','cereza','cerezas',
    'albaricoque','albaricoques','nectarina','nectarinas','paraguayo','paraguayos',
    'arandano','arandanos','frambuesa','frambuesas','mora','moras','granada','granadas',
    'higo','higos','coco','aguacate','aguacates','maracuya','pomelo','pomelos',
    'tomate','tomates','lechuga','lechugas','espinaca','espinacas','zanahoria',
    'zanahorias','cebolla','cebollas','ajo','ajos','pimiento','pimientos','calabacin',
    'calabacines','berenjena','berenjenas','pepino','pepinos','brocoli','coliflor',
    'coliflores','apio','nabo','nabos','rabano','rabanos','esparrago','esparragos',
    'alcachofa','alcachofas','puerro','puerros','champinon','champinones','seta',
    'setas','judia verde','judias verdes','maiz fresco','patata','patatas','papa',
    'papas','batata','batatas','boniato','verdura','verduras','fruta','frutas',
    'ensalada','ensaladas','col','repollo','coles','acelga','acelgas','rucula',
    'canonigos','escarola','calabaza','remolacha','remolachas','endibia','endibias',
  ]},
];

// Quita acentos y pasa a minúsculas para hacer matching robusto a "ñ", "á", etc.
function _normCat(s) {
  return (s || '').toLowerCase().normalize('NFD').replace(/[̀-ͯ]/g, '').trim();
}

function autoCategoryFor(name) {
  const n = _normCat(name);
  if (!n) return 'otros';
  const words = n.split(/[^a-z0-9]+/).filter(Boolean);
  // Match por palabra completa para keywords de una sola palabra (evita que
  // "lata" matchee dentro de "platanos"). Para keywords multi-palabra usamos
  // substring porque suelen ser frases descriptivas ("pasta de dientes").
  for (const r of AUTO_RULES) {
    for (const kw of r.kw) {
      if (kw.includes(' ')) {
        if (n.includes(kw)) return r.cat;
      } else if (words.includes(kw)) {
        return r.cat;
      }
    }
  }
  return 'otros';
}

// Sin listas por defecto: la app arranca vacía y el usuario crea o se une a
// una lista. Conservamos los nombres exportados (SEED_*) para no romper el
// resto del código que los referencia.
const SEED_LIST_ID = null;
const SEED_LISTS = [];

let _id = 1;
const nextId = () => `i${++_id}`;
const seedItem = (name, qty, cat, purchased=false, addedAgo=0) => ({
  id: nextId(),
  name,
  quantity: qty || '',
  category: cat,
  is_purchased: purchased,
  is_archived: false,
  created_at: Date.now() - addedAgo,
});

const SEED_PRODUCTS = {};

const FREQUENT = {
  es: ['Leche', 'Pan', 'Plátanos', 'Huevos', 'Tomates', 'Aguacate', 'Yogur', 'Café', 'Pollo', 'Aceite', 'Pasta', 'Arroz', 'Cebolla', 'Cerveza', 'Agua'],
  en: ['Milk', 'Bread', 'Bananas', 'Eggs', 'Tomatoes', 'Avocado', 'Yogurt', 'Coffee', 'Chicken', 'Olive oil', 'Pasta', 'Rice', 'Onion', 'Beer', 'Water'],
};

const SEED_HISTORY = {};

// Iconos minimal (line icons, currentColor)
const Icon = ({ name, size = 24, stroke = 2, ...rest }) => {
  const props = { width: size, height: size, viewBox: '0 0 24 24', fill: 'none', stroke: 'currentColor', strokeWidth: stroke, strokeLinecap: 'round', strokeLinejoin: 'round', ...rest };
  switch (name) {
    case 'list':         return <svg {...props}><path d="M8 6h13M8 12h13M8 18h13"/><circle cx="4" cy="6" r="1.2" fill="currentColor"/><circle cx="4" cy="12" r="1.2" fill="currentColor"/><circle cx="4" cy="18" r="1.2" fill="currentColor"/></svg>;
    case 'cart':         return <svg {...props}><path d="M3 4h2l2.5 12h11l2-8H6"/><circle cx="9" cy="20" r="1.5"/><circle cx="18" cy="20" r="1.5"/></svg>;
    case 'history':      return <svg {...props}><path d="M3 12a9 9 0 1 0 3-6.7"/><path d="M3 4v5h5"/><path d="M12 7v5l3 2"/></svg>;
    case 'stack':        return <svg {...props}><path d="M12 3l9 5-9 5-9-5 9-5z"/><path d="M3 13l9 5 9-5"/></svg>;
    case 'gear':         return <svg {...props}><circle cx="12" cy="12" r="3"/><path d="M19.4 15a1.7 1.7 0 0 0 .3 1.8l.1.1a2 2 0 1 1-2.8 2.8l-.1-.1a1.7 1.7 0 0 0-1.8-.3 1.7 1.7 0 0 0-1 1.5V21a2 2 0 1 1-4 0v-.1a1.7 1.7 0 0 0-1.1-1.5 1.7 1.7 0 0 0-1.8.3l-.1.1a2 2 0 1 1-2.8-2.8l.1-.1a1.7 1.7 0 0 0 .3-1.8 1.7 1.7 0 0 0-1.5-1H3a2 2 0 1 1 0-4h.1A1.7 1.7 0 0 0 4.6 9a1.7 1.7 0 0 0-.3-1.8l-.1-.1a2 2 0 1 1 2.8-2.8l.1.1a1.7 1.7 0 0 0 1.8.3H9a1.7 1.7 0 0 0 1-1.5V3a2 2 0 1 1 4 0v.1a1.7 1.7 0 0 0 1 1.5 1.7 1.7 0 0 0 1.8-.3l.1-.1a2 2 0 1 1 2.8 2.8l-.1.1a1.7 1.7 0 0 0-.3 1.8V9a1.7 1.7 0 0 0 1.5 1H21a2 2 0 1 1 0 4h-.1a1.7 1.7 0 0 0-1.5 1z"/></svg>;
    case 'plus':         return <svg {...props}><path d="M12 5v14M5 12h14"/></svg>;
    case 'check':        return <svg {...props}><path d="M5 12l5 5 9-11"/></svg>;
    case 'x':            return <svg {...props}><path d="M6 6l12 12M18 6L6 18"/></svg>;
    case 'mic':          return <svg {...props}><rect x="9" y="3" width="6" height="12" rx="3"/><path d="M5 11a7 7 0 0 0 14 0M12 18v3"/></svg>;
    case 'chevron-down': return <svg {...props}><path d="M6 9l6 6 6-6"/></svg>;
    case 'chevron-up':   return <svg {...props}><path d="M6 15l6-6 6 6"/></svg>;
    case 'chevron-right':return <svg {...props}><path d="M9 6l6 6-6 6"/></svg>;
    case 'chevron-left': return <svg {...props}><path d="M15 6l-6 6 6 6"/></svg>;
    case 'dots':         return <svg {...props}><circle cx="5" cy="12" r="1.6" fill="currentColor"/><circle cx="12" cy="12" r="1.6" fill="currentColor"/><circle cx="19" cy="12" r="1.6" fill="currentColor"/></svg>;
    case 'trash':        return <svg {...props}><path d="M4 7h16M9 7V4h6v3M6 7l1 13h10l1-13"/></svg>;
    case 'edit':         return <svg {...props}><path d="M4 20h4l11-11-4-4L4 16v4z"/></svg>;
    case 'share':        return <svg {...props}><circle cx="6" cy="12" r="2.5"/><circle cx="18" cy="6" r="2.5"/><circle cx="18" cy="18" r="2.5"/><path d="M8 11l8-4M8 13l8 4"/></svg>;
    case 'qr':           return <svg {...props}><rect x="3" y="3" width="7" height="7" rx="1"/><rect x="14" y="3" width="7" height="7" rx="1"/><rect x="3" y="14" width="7" height="7" rx="1"/><path d="M14 14h3v3M21 14v7M14 21h3"/></svg>;
    case 'sun':          return <svg {...props}><circle cx="12" cy="12" r="4"/><path d="M12 2v2M12 20v2M4 12H2M22 12h-2M5 5l1.5 1.5M17.5 17.5L19 19M5 19l1.5-1.5M17.5 6.5L19 5"/></svg>;
    case 'moon':         return <svg {...props}><path d="M21 12.8A9 9 0 1 1 11.2 3a7 7 0 0 0 9.8 9.8z"/></svg>;
    case 'copy':         return <svg {...props}><rect x="9" y="9" width="11" height="11" rx="2"/><path d="M5 15V5a2 2 0 0 1 2-2h10"/></svg>;
    case 'sparkle':      return <svg {...props}><path d="M12 3l1.8 5.2L19 10l-5.2 1.8L12 17l-1.8-5.2L5 10l5.2-1.8z"/></svg>;
    case 'sparkle-sm':   return <svg {...props}><path d="M12 4l1.4 4 4 1.4-4 1.4-1.4 4-1.4-4-4-1.4 4-1.4z"/></svg>;
    case 'undo':         return <svg {...props}><path d="M9 14l-5-5 5-5"/><path d="M4 9h11a5 5 0 0 1 0 10h-2"/></svg>;
    case 'lightning':    return <svg {...props}><path d="M13 3L4 14h6l-1 7 9-11h-6l1-7z"/></svg>;
    case 'people':       return <svg {...props}><circle cx="9" cy="8" r="3.2"/><path d="M2.5 20a6.5 6.5 0 0 1 13 0"/><circle cx="17" cy="9" r="2.5"/><path d="M22 19a5 5 0 0 0-5-5"/></svg>;
    case 'arrow-right':  return <svg {...props}><path d="M5 12h14M13 6l6 6-6 6"/></svg>;
    case 'logout':       return <svg {...props}><path d="M16 17l5-5-5-5M21 12H9M9 21H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h4"/></svg>;
    case 'undo-circle':  return <svg {...props}><circle cx="12" cy="12" r="9"/><path d="M9 9l-3 3 3 3M6 12h7a3 3 0 0 1 0 6h-1"/></svg>;
    case 'flame':        return <svg {...props}><path d="M12 3c0 4-5 6-5 11a5 5 0 0 0 10 0c0-2-1-3-1-5 0 0-1 1-2.5 1C12 10 14 7 12 3z"/></svg>;
    case 'download':     return <svg {...props}><path d="M12 3v12M7 10l5 5 5-5"/><path d="M5 19h14"/></svg>;

    // ─── Glyphs de categorías (line-icons coherentes con el resto) ───
    case 'cat-oil':       return <svg {...props}><path d="M9 2h6M10 2v3l-2 3v11a2 2 0 0 0 2 2h4a2 2 0 0 0 2-2V8l-2-3V2"/><path d="M11 13h2"/></svg>;
    case 'cat-soda':      return <svg {...props}><rect x="7" y="6" width="10" height="15" rx="2"/><path d="M9 6V4h6v2"/><path d="M7 11h10"/></svg>;
    case 'cat-snack':     return <svg {...props}><path d="M6 3h12l-1 18H7L6 3z"/><path d="M6 3l-1 2 1 2M18 3l1 2-1 2"/></svg>;
    case 'cat-rice':      return <svg {...props}><path d="M3 13a9 4 0 0 0 18 0"/><path d="M3 13h18"/><circle cx="9" cy="9" r="0.8" fill="currentColor"/><circle cx="13" cy="8" r="0.8" fill="currentColor"/><circle cx="15" cy="11" r="0.8" fill="currentColor"/><circle cx="11" cy="11" r="0.8" fill="currentColor"/></svg>;
    case 'cat-candy':     return <svg {...props}><ellipse cx="12" cy="12" rx="5" ry="3.5"/><path d="M7 10l-3-2 1 4 2-2zM17 10l3-2-1 4-2-2z"/></svg>;
    case 'cat-baby':      return <svg {...props}><circle cx="12" cy="13" r="6"/><circle cx="10" cy="12" r="0.8" fill="currentColor"/><circle cx="14" cy="12" r="0.8" fill="currentColor"/><path d="M10 15c1 1 3 1 4 0"/><path d="M9 4c0 2 1 3 3 3s3-1 3-3"/></svg>;
    case 'cat-wine':      return <svg {...props}><path d="M9 3h6l-1 6a3 3 0 0 1-2 3v8M12 12a3 3 0 0 1-2-3l-1-6"/><path d="M9 21h6"/></svg>;
    case 'cat-coffee':    return <svg {...props}><path d="M5 9h12v6a4 4 0 0 1-4 4H9a4 4 0 0 1-4-4V9z"/><path d="M17 11h2a2 2 0 0 1 0 4h-2"/><path d="M8 4v3M12 4v3"/></svg>;
    case 'cat-meat':      return <svg {...props}><path d="M5 13a7 7 0 1 1 14 0c0 4-3 7-7 7s-7-3-7-7z"/><circle cx="9" cy="11" r="1.6"/></svg>;
    case 'cat-cereal':    return <svg {...props}><path d="M3 12h18"/><path d="M4 12a8 5 0 0 0 16 0"/><path d="M14 4l3 8M11 4l1 8M8 4l-1 8"/></svg>;
    case 'cat-cheese':    return <svg {...props}><path d="M3 17l9-11 9 6v5z"/><circle cx="9" cy="14" r="0.8" fill="currentColor"/><circle cx="14" cy="13" r="0.8" fill="currentColor"/><circle cx="16" cy="15" r="0.8" fill="currentColor"/></svg>;
    case 'cat-ice':       return <svg {...props}><path d="M12 2v20M4 7l16 10M4 17l16-10"/><path d="M9 4l3-2 3 2M9 20l3 2 3-2M2 12l2-1 2 1M22 12l-2-1-2 1"/></svg>;
    case 'cat-can':       return <svg {...props}><ellipse cx="12" cy="6" rx="7" ry="2"/><path d="M5 6v12c0 1.1 3.1 2 7 2s7-.9 7-2V6"/><path d="M5 11c0 1.1 3.1 2 7 2s7-.9 7-2"/></svg>;
    case 'cat-hair':      return <svg {...props}><circle cx="6" cy="18" r="3"/><circle cx="18" cy="18" r="3"/><path d="M8 16L20 4M16 16L4 4"/></svg>;
    case 'cat-lotion':    return <svg {...props}><rect x="8" y="7" width="8" height="14" rx="2"/><path d="M9 7V5h6v2"/><path d="M11 5l-2-2h6l-2 2"/></svg>;
    case 'cat-pill':      return <svg {...props}><rect x="2" y="9" width="20" height="6" rx="3"/><path d="M12 9v6"/></svg>;
    case 'cat-leaf':      return <svg {...props}><path d="M5 19c0-9 6-14 14-14 0 8-5 14-14 14z"/><path d="M5 19l9-9"/></svg>;
    case 'cat-milk':      return <svg {...props}><path d="M7 4h10l1 4v12a1 1 0 0 1-1 1H7a1 1 0 0 1-1-1V8z"/><path d="M9 4l3 4M15 4l-3 4"/><rect x="9" y="13" width="6" height="4"/></svg>;
    case 'cat-broom':     return <svg {...props}><path d="M14 3l7 7-3 3-7-7z"/><path d="M11 6l-9 9 1 5 5 1 9-9"/><path d="M3 19l4 1"/></svg>;
    case 'cat-lipstick':  return <svg {...props}><path d="M9 2l4 4-2 4h-4l2-4-2-4z"/><rect x="7" y="10" width="6" height="11" rx="1"/></svg>;
    case 'cat-fish':      return <svg {...props}><path d="M3 12c4-5 9-5 12 0-3 5-8 5-12 0z"/><path d="M15 12l5-3v6z"/><circle cx="7" cy="11" r="0.6" fill="currentColor"/></svg>;
    case 'cat-paw':       return <svg {...props}><ellipse cx="12" cy="16" rx="4" ry="3"/><ellipse cx="6" cy="11" rx="1.5" ry="2"/><ellipse cx="10" cy="8" rx="1.5" ry="2"/><ellipse cx="14" cy="8" rx="1.5" ry="2"/><ellipse cx="18" cy="11" rx="1.5" ry="2"/></svg>;
    case 'cat-bread':     return <svg {...props}><path d="M4 14a8 6 0 0 1 16 0v3a1 1 0 0 1-1 1H5a1 1 0 0 1-1-1v-3z"/><path d="M9 11l1 4M13 11l1 4M16 11l-1 4"/></svg>;
    case 'cat-pizza':     return <svg {...props}><path d="M12 3l9 16H3z"/><circle cx="10" cy="13" r="0.9" fill="currentColor"/><circle cx="13" cy="11" r="0.9" fill="currentColor"/><circle cx="14" cy="16" r="0.9" fill="currentColor"/></svg>;
    case 'cat-flan':      return <svg {...props}><path d="M5 13a7 4 0 0 1 14 0v0H5z"/><path d="M6 13l1 8h10l1-8"/><circle cx="12" cy="6" r="2"/><path d="M12 8v5"/></svg>;
    case 'cat-juice':     return <svg {...props}><path d="M6 7h12l-2 14H8L6 7z"/><path d="M9 7V3M9 3l4-1"/><path d="M7 12h10"/></svg>;
    case 'cat-box':       return <svg {...props}><path d="M3 7l9-4 9 4-9 4-9-4z"/><path d="M3 7v10l9 4 9-4V7"/><path d="M12 11v10"/></svg>;
    default: return null;
  }
};

function relativeTime(at, lang) {
  const t = I18N[lang];
  const diff = Date.now() - at;
  const m = Math.floor(diff / 60000);
  if (m < 1) return lang === 'es' ? 'ahora' : 'now';
  if (m < 60) return `${m}m`;
  const h = Math.floor(m / 60);
  if (h < 24) return `${h}h`;
  const d = Math.floor(h / 24);
  if (d === 1) return t.yesterday;
  if (d < 7) return t.daysAgo.replace('{n}', d);
  return new Date(at).toLocaleDateString(lang === 'es' ? 'es-ES' : 'en-US', { day: 'numeric', month: 'short' });
}

function formatDate(at, lang) {
  return new Date(at).toLocaleDateString(lang === 'es' ? 'es-ES' : 'en-US', { day: 'numeric', month: 'short', year: 'numeric' });
}

function dayBucket(at, lang) {
  const t = I18N[lang];
  const d1 = new Date(at);
  const d2 = new Date();
  d1.setHours(0,0,0,0);
  d2.setHours(0,0,0,0);
  const diff = (d2 - d1) / (1000*60*60*24);
  if (diff === 0) return t.today_full;
  if (diff === 1) return t.yesterday_full;
  if (diff < 7) return new Date(at).toLocaleDateString(lang === 'es' ? 'es-ES' : 'en-US', { weekday: 'long' });
  return t.earlier;
}

// Cantidad: entero positivo o cadena vacía. Acepta string (con dígitos al
// inicio, ej. "2 kg" → 2) o number. Se aplica en cada read/write para que
// los datos legacy con unidades ("1 kg", "500 g") se conviertan al vuelo.
function normalizeQty(v) {
  if (v == null || v === '') return '';
  if (typeof v === 'number') {
    if (!Number.isFinite(v) || v <= 0) return '';
    return Math.floor(v);
  }
  const s = String(v).trim();
  if (!s) return '';
  const m = s.match(/-?\d+/);
  if (!m) return '';
  const n = parseInt(m[0], 10);
  if (!Number.isFinite(n) || n <= 0) return '';
  return n;
}

// Platform detection — for hybrid iOS/Android tweaks
const PLATFORM = (() => {
  if (typeof navigator === 'undefined') return 'web';
  const ua = navigator.userAgent || '';
  if (/iPad|iPhone|iPod/.test(ua)) return 'ios';
  if (/Android/i.test(ua)) return 'android';
  return 'web';
})();

// Origen canónico para URLs compartidas. En Capacitor (iOS/Android) `window.
// location.origin` es `capacitor://localhost`, inútil fuera de la app. Forzamos
// el dominio público para que el mismo link funcione en web, iOS y Android.
const SHARE_ORIGIN = 'https://shop.jarsss8.es';

Object.assign(window, {
  I18N, CATEGORIES, AUTO_RULES, autoCategoryFor,
  SEED_LIST_ID, SEED_LISTS, SEED_PRODUCTS, SEED_HISTORY, FREQUENT,
  Icon, CatGlyph, relativeTime, formatDate, dayBucket, nextId, PLATFORM, normalizeQty,
  SHARE_ORIGIN,
});
