// Gustai Lab design tokens + shared primitives
const GL = {
  // Palette
  teal: '#59DFE8',
  tealDim: '#2FB9C2',
  ink: '#0A0A0A',
  inkSoft: '#111A1C',
  darkBg: '#0E1B1D',
  darkSurface: '#162628',
  darkBorder: 'rgba(255,255,255,0.08)',
  offwhite: '#F6F8F8',
  paper: '#FFFFFF',
  line: '#E8ECEC',
  muted: '#8A9698',
  mutedDark: 'rgba(255,255,255,0.55)',

  // Type
  display: "'Archivo Black', 'Arial Black', Impact, sans-serif",
  body: "'Inter', -apple-system, system-ui, sans-serif",
  mono: "'JetBrains Mono', ui-monospace, Menlo, monospace",
};

// Inject fonts + base
function GLFonts() {
  return (
    <style>{`
      @import url('https://fonts.googleapis.com/css2?family=Archivo+Black&family=Inter:wght@400;500;600;700;800&family=JetBrains+Mono:wght@400;500;700&display=swap');
      *, *::before, *::after { box-sizing: border-box; }
      body, html { margin: 0; padding: 0; font-family: ${GL.body}; -webkit-font-smoothing: antialiased; }
      button { font-family: inherit; border: none; background: none; cursor: pointer; padding: 0; color: inherit; }
      input, textarea { font-family: inherit; }
      .gl-display { font-family: ${GL.display}; letter-spacing: -0.02em; text-transform: uppercase; }
      .gl-mono { font-family: ${GL.mono}; }
      .gl-kicker { font-family: ${GL.body}; font-weight: 700; font-size: 10px; letter-spacing: 0.22em; text-transform: uppercase; }
      .gl-noscroll::-webkit-scrollbar { display: none; }
      .gl-noscroll { -ms-overflow-style: none; scrollbar-width: none; }
      @keyframes gl-pulse { 0%,100%{opacity:1} 50%{opacity:.4} }
      @keyframes gl-spin { to { transform: rotate(360deg); } }
      @keyframes gl-slide-up { from { transform: translateY(8px); opacity: 0 } to { transform: translateY(0); opacity: 1 } }
      @keyframes gl-fade { from{opacity:0} to{opacity:1} }
      .gl-fade { animation: gl-fade 0.25s ease-out both; }
      .gl-slide-up { animation: gl-slide-up 0.3s ease-out both; }
    `}</style>
  );
}

// Placeholder image: striped SVG with monospace caption
function GLImage({ src, alt, label, ratio = '4/5', radius = 12, dark = false, style = {} }) {
  const [err, setErr] = React.useState(false);
  if (src && !err) {
    return (
      <div style={{ aspectRatio: ratio, width: '100%', borderRadius: radius, overflow: 'hidden', background: dark ? '#222' : '#E8ECEC', position: 'relative', ...style }}>
        <img src={src} alt={alt || label} onError={() => setErr(true)}
          style={{ width: '100%', height: '100%', objectFit: 'cover', display: 'block' }}/>
      </div>
    );
  }
  const stripe = dark ? 'rgba(255,255,255,0.04)' : 'rgba(10,10,10,0.04)';
  return (
    <div style={{
      aspectRatio: ratio, width: '100%', borderRadius: radius, overflow: 'hidden',
      background: `repeating-linear-gradient(45deg, ${dark ? '#1a2a2c' : '#ECEFF0'} 0 10px, ${stripe} 10px 20px)`,
      display: 'flex', alignItems: 'center', justifyContent: 'center',
      color: dark ? 'rgba(255,255,255,0.55)' : 'rgba(10,10,10,0.45)',
      fontFamily: GL.mono, fontSize: 10, letterSpacing: 0.1, textAlign: 'center', padding: 12,
      ...style,
    }}>
      {label || alt || 'IMG'}
    </div>
  );
}

// Primary button (dark, pill-less rectangular iOS-ish)
function GLButton({ children, onClick, variant = 'primary', icon, style = {}, disabled }) {
  const base = {
    display: 'flex', alignItems: 'center', justifyContent: 'center', gap: 10,
    width: '100%', height: 56, borderRadius: 8,
    fontFamily: GL.body, fontWeight: 800, fontSize: 14,
    letterSpacing: '0.18em', textTransform: 'uppercase',
    transition: 'transform .12s ease, opacity .15s',
    opacity: disabled ? 0.4 : 1, cursor: disabled ? 'not-allowed' : 'pointer',
  };
  const variants = {
    primary: { background: GL.ink, color: '#fff' },
    teal: { background: GL.teal, color: GL.ink },
    outline: { background: 'transparent', color: GL.ink, border: `1.5px solid ${GL.ink}` },
    ghost: { background: 'transparent', color: GL.ink },
    darkPrimary: { background: '#fff', color: GL.ink },
  };
  return (
    <button onClick={disabled ? undefined : onClick}
      onMouseDown={e => !disabled && (e.currentTarget.style.transform = 'scale(0.98)')}
      onMouseUp={e => (e.currentTarget.style.transform = '')}
      onMouseLeave={e => (e.currentTarget.style.transform = '')}
      style={{ ...base, ...variants[variant], ...style }}>
      {children}{icon}
    </button>
  );
}

// Tab bar — middle slot swaps with shop mode:
//   alc → "Cart" (shopping-cart icon, one-time order)
//   sub → "Box"  (box icon, recurring standing-order template)
// Both ids are 'box' so routing/active state stays unified — only the visual
// presentation changes per mode. Same for the count badge.
function GLTabBar({ active, onNav, cartCount = 0, dark = false, shopMode = 'alc' }) {
  const middleTab = shopMode === 'sub'
    ? { id: 'box', label: 'Box',  icon: 'M3 7l9-4 9 4v10l-9 4-9-4V7zM3 7l9 4 9-4M12 11v10' }
    : { id: 'box', label: 'Cart', icon: 'M6 6h15l-1.5 9h-13zM6 6L5 3H2M9 21a1 1 0 1 0 0-2 1 1 0 0 0 0 2zM18 21a1 1 0 1 0 0-2 1 1 0 0 0 0 2z' };
  const tabs = [
    { id: 'home',  label: 'Home',  icon: 'M3 11l9-8 9 8v10a1 1 0 0 1-1 1h-5v-7h-6v7H4a1 1 0 0 1-1-1V11z' },
    { id: 'lab',   label: 'Lab',   icon: 'M9 2v6.5L3.5 18.3A2 2 0 0 0 5.2 21.5h13.6a2 2 0 0 0 1.7-3.2L15 8.5V2M8 2h8M9 14h6' },
    middleTab,
    // Mario AI chat replaces Profile in the bottom nav. Profile lives in the topbar now.
    { id: 'mario', label: 'Mario', icon: 'M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z' },
  ];
  const bg = dark ? 'rgba(14,27,29,0.94)' : 'rgba(255,255,255,0.94)';
  const border = dark ? GL.darkBorder : GL.line;
  return (
    <div style={{
      position: 'absolute', left: 0, right: 0, bottom: 0, zIndex: 40,
      background: bg, backdropFilter: 'blur(18px)', WebkitBackdropFilter: 'blur(18px)',
      borderTop: `1px solid ${border}`,
      padding: '10px 12px 28px',
      display: 'flex', justifyContent: 'space-around', alignItems: 'center',
    }}>
      {tabs.map(t => {
        const on = t.id === active;
        const color = on ? (dark ? GL.teal : GL.ink) : (dark ? GL.mutedDark : GL.muted);
        return (
          <button key={t.id} onClick={() => onNav(t.id)}
            style={{ display: 'flex', flexDirection: 'column', alignItems: 'center', gap: 4, flex: 1, position: 'relative' }}>
            <svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke={color} strokeWidth="1.8" strokeLinejoin="round" strokeLinecap="round">
              <path d={t.icon}/>
            </svg>
            <span style={{ fontSize: 10, fontWeight: 700, letterSpacing: '0.08em', textTransform: 'uppercase', color }}>{t.label}</span>
            {t.id === 'box' && cartCount > 0 && (
              <span style={{
                position: 'absolute', top: -4, right: 'calc(50% - 18px)',
                background: GL.teal, color: GL.ink, fontSize: 9, fontWeight: 800,
                minWidth: 16, height: 16, borderRadius: 10, display: 'flex', alignItems: 'center', justifyContent: 'center',
                padding: '0 4px',
              }}>{cartCount}</span>
            )}
          </button>
        );
      })}
    </div>
  );
}

// Top bar with logo/back
function GLTopBar({ title = 'Gustai Lab', onBack, cartCount = 0, onCart, dark = false, right, center }) {
  const fg = dark ? '#fff' : GL.ink;
  const border = dark ? GL.darkBorder : GL.line;
  const bg = dark ? 'rgba(14,27,29,0.92)' : 'rgba(255,255,255,0.92)';
  return (
    <div style={{
      position: 'sticky', top: 0, zIndex: 30,
      background: bg, backdropFilter: 'blur(16px)', WebkitBackdropFilter: 'blur(16px)',
      borderBottom: `1px solid ${border}`,
      display: 'flex', alignItems: 'center', justifyContent: 'space-between',
      padding: '64px 18px 14px', height: 104, boxSizing: 'border-box',
    }}>
      <div style={{ width: 60, display: 'flex', alignItems: 'center' }}>
        {onBack && (
          <button onClick={onBack} style={{ width: 32, height: 32, display: 'grid', placeItems: 'center' }}>
            <svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke={fg} strokeWidth="2.2" strokeLinecap="round" strokeLinejoin="round">
              <path d="M19 12H5M12 19l-7-7 7-7"/>
            </svg>
          </button>
        )}
      </div>
      <div style={{ flex: 1, textAlign: 'center', display: 'flex', justifyContent: 'center', alignItems: 'center' }}>
        {center || (
          <div className="gl-display" style={{ fontSize: 16, color: fg, letterSpacing: '0.06em' }}>{title}</div>
        )}
      </div>
      <div style={{ width: 60, display: 'flex', justifyContent: 'flex-end', alignItems: 'center', gap: 8 }}>
        {right}
        {onCart && (
          <button onClick={onCart} style={{ width: 32, height: 32, display: 'grid', placeItems: 'center', position: 'relative' }}>
            <svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke={fg} strokeWidth="1.8" strokeLinejoin="round" strokeLinecap="round">
              <path d="M6 2l1.5 4h10L19 2M4 6h16l-1.5 13a2 2 0 0 1-2 1.8H7.5a2 2 0 0 1-2-1.8L4 6zM9 11v4M15 11v4"/>
            </svg>
            {cartCount > 0 && (
              <span style={{
                position: 'absolute', top: -2, right: -4,
                background: GL.teal, color: GL.ink, fontSize: 9, fontWeight: 800,
                minWidth: 16, height: 16, borderRadius: 10, display: 'grid', placeItems: 'center',
                padding: '0 4px',
              }}>{cartCount}</span>
            )}
          </button>
        )}
      </div>
    </div>
  );
}

// Diet label registry — used by DietBadges + filtering
// label = display text, color = chip background (light), fg = text color
const GL_DIET_LABELS = {
  'vegetarian':       { label: 'Vegetarian',  color: '#E8F5E9', fg: '#1B5E20', kind: 'positive' },
  'vegan':            { label: 'Vegan',       color: '#E8F5E9', fg: '#1B5E20', kind: 'positive' },
  'gluten-free':      { label: 'Gluten-Free', color: '#E8F5E9', fg: '#1B5E20', kind: 'positive' },
  'dairy-free':       { label: 'Dairy-Free',  color: '#E8F5E9', fg: '#1B5E20', kind: 'positive' },
  'contains-gluten':  { label: 'Gluten',      color: '#FFF3E0', fg: '#B45309', kind: 'allergen' },
  'contains-dairy':   { label: 'Dairy',       color: '#FFF3E0', fg: '#B45309', kind: 'allergen' },
  'contains-eggs':    { label: 'Eggs',        color: '#FFF3E0', fg: '#B45309', kind: 'allergen' },
  'contains-nuts':    { label: 'Nuts',        color: '#FFF3E0', fg: '#B45309', kind: 'allergen' },
  'contains-shellfish': { label: 'Shellfish', color: '#FFF3E0', fg: '#B45309', kind: 'allergen' },
  'contains-pork':    { label: 'Pork',        color: '#FFF3E0', fg: '#B45309', kind: 'allergen' },
};

// Compact diet badge row. mode: 'compact' (max 3, dots overflow) | 'full'
function GLDietBadges({ labels = [], mode = 'compact', dark = false }) {
  if (!labels || labels.length === 0) return null;
  const items = mode === 'compact' ? labels.slice(0, 3) : labels;
  const overflow = mode === 'compact' && labels.length > 3 ? labels.length - 3 : 0;
  return (
    <div style={{ display: 'flex', flexWrap: 'wrap', gap: 4, alignItems: 'center' }}>
      {items.map(key => {
        const meta = GL_DIET_LABELS[key];
        if (!meta) return null;
        const bg = dark ? (meta.kind === 'positive' ? 'rgba(89,223,232,0.12)' : 'rgba(255,255,255,0.08)') : meta.color;
        const fg = dark ? (meta.kind === 'positive' ? GL.teal : 'rgba(255,255,255,0.85)') : meta.fg;
        return (
          <span key={key} style={{
            background: bg, color: fg, fontSize: 9, fontWeight: 700,
            letterSpacing: '0.06em', textTransform: 'uppercase',
            padding: '3px 6px', borderRadius: 4, lineHeight: 1.2, whiteSpace: 'nowrap',
          }}>{meta.label}</span>
        );
      })}
      {overflow > 0 && (
        <span style={{ fontSize: 9, color: dark ? GL.mutedDark : GL.muted, fontWeight: 700 }}>+{overflow}</span>
      )}
    </div>
  );
}

// Product/set data
// All items are category 'sets' for launch (single-category UX). diet_labels drive badge UI.
const GL_PASTA = [
  { id: 'truffle',  name: 'Truffle Mafaldine',    pair: 'Creamy Truffle Sauce', price: 350, cat: 'sets',  tags: ['BESTSELLER'], diet_labels: ['vegetarian','contains-gluten','contains-eggs','contains-dairy'], img: 'https://images.unsplash.com/photo-1622973536968-3ead9e780960?w=800&q=80',
    short_desc: 'Hand-rolled mafaldine ribbons drenched in black truffle cream.',
    long_desc: 'Made in small batches each morning. Pairs beautifully with our house-made focaccia and a chilled glass of Vermentino.',
    ingredients: '• Semolina flour (Imported from Italy)\n• Organic eggs\n• Fresh black summer truffle\n• White truffle oil\n• Sea salt',
    method: 'Bronze-extruded through custom dies for a rough, porous surface. Cold-pressed at under 40°C to preserve protein structure. Slow-dried for 24 hours minimum.',
    cooking_instr: '1. Bring a large pot of salted water to a rolling boil.\n2. Add pasta and cook 3–4 minutes until al dente.\n3. Reserve ½ cup pasta water, drain, and toss with sauce.',
    allergens: 'Contains: Gluten (wheat), Eggs. May contain traces of nuts. Dairy in sauce.',
    storage_info: 'Keep refrigerated below 4°C. Best consumed within 3 days of delivery. Can be frozen for up to 1 month.',
    subscribe_note: 'Cancel anytime. Free delivery over ฿1000.' },
  { id: 'squid',   name: 'Squid Ink Tagliolini',  pair: 'Spicy Seafood Sauce',  price: 320, cat: 'sets',  tags: ['NEW'], diet_labels: ['contains-gluten','contains-eggs','contains-shellfish'], img: 'https://images.unsplash.com/photo-1551183053-bf91a1d81141?w=800&q=80',
    short_desc: 'Jet-black tagliolini with a bold spicy seafood sauce.',
    long_desc: 'Our squid ink is sourced fresh daily from Phuket fishermen. Intense, briny, and utterly addictive.',
    ingredients: '• Semolina flour\n• Organic eggs\n• Fresh squid ink\n• Sea salt',
    method: 'Hand-rolled to 1.5mm thickness then cut on a chitarra frame. Squid ink folded in during kneading for colour depth. Air-dried at room temperature for 4 hours.',
    cooking_instr: '1. Boil salted water. Cook pasta 2–3 minutes.\n2. Warm sauce separately.\n3. Toss together and serve immediately.',
    allergens: 'Contains: Gluten (wheat), Eggs, Molluscs (squid). May contain traces of shellfish and nuts.',
    storage_info: 'Keep refrigerated below 4°C. Best consumed within 2 days.',
    subscribe_note: 'Cancel anytime. Free delivery over ฿1000.' },
  { id: 'rigatoni', name: 'Classic Rigatoni',     pair: 'Wagyu Bolognese',       price: 280, cat: 'sets', tags: ['POPULAR'], diet_labels: ['contains-gluten','contains-eggs'], img: 'https://images.unsplash.com/photo-1587740908075-9e245311e158?w=800&q=80',
    short_desc: 'Bronze-extruded rigatoni built for thick, hearty sauces.',
    long_desc: 'Our ridged rigatoni grips every drop of the slow-braised Wagyu bolognese. A Gustai Lab cornerstone.',
    ingredients: '• Durum wheat semolina\n• Organic eggs\n• Sea salt',
    method: 'Extruded through bronze dies under high pressure for maximum surface roughness. Short-cut and ridged to grip thick sauces. Dried slowly over 36 hours at 38°C.',
    cooking_instr: '1. Boil generously salted water. Cook 5–6 minutes.\n2. Reserve pasta water.\n3. Toss with bolognese over low heat.',
    allergens: 'Contains: Gluten (wheat), Eggs. May contain traces of nuts and dairy.',
    storage_info: 'Refrigerate below 4°C. Best within 3 days. Freezes well.',
    subscribe_note: 'Cancel anytime. Free delivery over ฿1000.' },
  { id: 'burrata',  name: 'Burrata & Pomodoro',   pair: 'Tomato Basil Sauce',    price: 400, cat: 'sets', tags: ['FRESH'], diet_labels: ['vegetarian','contains-gluten','contains-eggs','contains-dairy'], img: 'https://images.unsplash.com/photo-1565299624946-b28f40a0ae38?w=800&q=80',
    short_desc: 'Pillowy paccheri with Phuket heirloom tomatoes and creamy burrata.',
    long_desc: 'Made in small batches each morning. Pairs beautifully with our house-made focaccia and a chilled glass of Vermentino.',
    ingredients: '• Semolina flour\n• Organic eggs\n• Heirloom tomatoes\n• Fresh basil\n• Sea salt',
    method: 'Large-format paccheri shaped in a smooth bronze die and scored for sauce adhesion. Short-dried at ambient temperature to retain a silky interior. Paired with a cold-crush tomato sauce.',
    cooking_instr: '1. Cook pasta 4–5 minutes in salted water.\n2. Warm sauce gently — do not boil.\n3. Plate pasta, add sauce, top with burrata.',
    allergens: 'Contains: Gluten (wheat), Eggs, Milk (burrata). Suitable for vegetarians. May contain traces of nuts.',
    storage_info: 'Refrigerate below 4°C. Best consumed within 2 days.',
    subscribe_note: 'Cancel anytime. Free delivery over ฿1000.' },
  { id: 'pesto',    name: 'Pesto alla Genovese',  pair: 'Pine Nut & Basil',      price: 300, cat: 'sets',  tags: ['CLASSIC'], diet_labels: ['vegetarian','contains-gluten','contains-eggs','contains-dairy','contains-nuts'], img: 'https://images.unsplash.com/photo-1473093226795-af9932fe5856?w=800&q=80',
    short_desc: 'Trofie-style pasta with a vivid cold-pressed Genovese pesto.',
    long_desc: 'Our basil is sourced from a single organic farm in Chiang Rai. The pesto is stone-ground the same morning.',
    ingredients: '• Semolina flour\n• Organic eggs\n• Fresh basil\n• Pine nuts\n• Parmigiano Reggiano\n• Extra virgin olive oil\n• Sea salt',
    method: 'Hand-twisted trofie rolled individually to create the spiral that traps pesto in each groove. Pesto stone-ground to order — never blended — for a coarser, more aromatic texture.',
    cooking_instr: '1. Cook pasta 3–4 minutes. Reserve ¼ cup pasta water.\n2. Never heat pesto. Toss cold with pasta off the heat.\n3. Loosen with pasta water as needed.',
    allergens: 'Contains: Gluten (wheat), Eggs, Milk, Tree nuts (pine nuts). May contain traces of other nuts.',
    storage_info: 'Refrigerate below 4°C. Consume within 3 days. Do not freeze pesto sauce.',
    subscribe_note: 'Cancel anytime. Free delivery over ฿1000.' },
  { id: 'cacio',    name: 'Cacio e Pepe',         pair: 'Pecorino Romano',        price: 290, cat: 'sets',  tags: ['CLASSIC'], diet_labels: ['vegetarian','contains-gluten','contains-eggs','contains-dairy'], img: 'https://images.unsplash.com/photo-1556761223-4c4282c73f77?w=800&q=80',
    short_desc: 'Three ingredients. Zero compromise. The Roman original.',
    long_desc: 'Spaghetti alla chitarra with aged Pecorino Romano and cracked Tellicherry pepper. Simplicity perfected.',
    ingredients: '• Semolina flour\n• Organic eggs\n• Aged Pecorino Romano\n• Tellicherry black pepper\n• Sea salt',
    method: 'Cut on a traditional chitarra (guitar) wire frame to achieve square cross-section spaghetti. Dried at 36°C for 20 hours. The cheese sauce is emulsified tableside with only pasta water — no cream.',
    cooking_instr: '1. Cook pasta 3–4 minutes. Reserve ½ cup pasta water.\n2. Bloom pepper in a dry pan.\n3. Toss pasta with pepper, cheese, and pasta water off heat until creamy.',
    allergens: 'Contains: Gluten (wheat), Eggs, Milk (Pecorino Romano). May contain traces of nuts. Suitable for vegetarians.',
    storage_info: 'Refrigerate below 4°C. Best consumed within 3 days.',
    subscribe_note: 'Cancel anytime. Free delivery over ฿1000.' },
];

// ── Weekly menu mock data (used by subscription screens) ──────────────────────
const GL_WEEKLY_MENU = {
  week_start: '2026-04-21',
  week_label: 'Week of 21 Apr',
  theme: 'Truffle Season',
  dispatch_date: '2026-04-24',
  cutoff_at: '2026-04-22T18:00:00+07:00',
  items: [
    { id:'wmi-1', product_id:'truffle',  name:'Truffle Mafaldine',    variant:'Single (200g)', price:380, available_qty:24, reserved_qty:8,  feature_badge:'CHEF PICK',  weight_g:200,
      img:'https://images.unsplash.com/photo-1621996346565-e3dbc646d9a9?w=800&auto=format&fit=crop' },
    { id:'wmi-2', product_id:'squid',    name:'Squid Ink Tagliolini', variant:'Double (400g)', price:640, available_qty:8,  reserved_qty:4,  feature_badge:'LIMITED',    weight_g:400,
      img:'https://images.unsplash.com/photo-1563379926898-05f4575a45d8?w=800&auto=format&fit=crop' },
    { id:'wmi-3', product_id:'rigatoni', name:'Classic Rigatoni',     variant:'Single (200g)', price:280, available_qty:30, reserved_qty:6,  feature_badge:'BESTSELLER', weight_g:200,
      img:'https://images.unsplash.com/photo-1555949258-eb67b1ef0ceb?w=800&auto=format&fit=crop' },
    { id:'wmi-4', product_id:'burrata',  name:'Burrata & Pomodoro',   variant:'Family (1kg)',  price:1240,available_qty:12, reserved_qty:3,  feature_badge:'NEW',        weight_g:1000,
      img:'https://images.unsplash.com/photo-1598866594230-a7c12756260f?w=800&auto=format&fit=crop' },
    { id:'wmi-5', product_id:'pesto',    name:'Pesto alla Genovese',  variant:'Single (200g)', price:300, available_qty:20, reserved_qty:5,  feature_badge:null,         weight_g:200,
      img:'https://images.unsplash.com/photo-1473093295043-cdd812d0e601?w=800&auto=format&fit=crop' },
    { id:'wmi-6', product_id:'cacio',    name:'Cacio e Pepe',         variant:'Double (400g)', price:580, available_qty:15, reserved_qty:4,  feature_badge:'CLASSIC',    weight_g:400,
      img:'https://images.unsplash.com/photo-1612874742237-6526221588e3?w=800&auto=format&fit=crop' },
  ],
};

Object.assign(window, { GL, GLFonts, GLImage, GLButton, GLTabBar, GLTopBar, GLDietBadges, GL_DIET_LABELS, GL_PASTA, GL_WEEKLY_MENU });
