nach oben
`); return; // skip bottle calc row for spirits base } rows.push(``); shoppingLines.push(`${bottles} × ${sizeL}l ${label.toLowerCase()}`); } if (res.beer) pushRow('Bier', res.beer.liters, sizes.beer); if (res.wine) pushRow('Wein', res.wine.liters, sizes.wine); if (res.sparkling) pushRow('Sekt/Prosecco', res.sparkling.liters, sizes.sparkling); if (res.soft) pushRow('Softdrinks', res.soft.liters, sizes.soft); if (res.water) pushRow('Wasser', res.water.liters, sizes.water); if (res.spirits) pushRow('Longdrinks/Spirituosen', res.spirits.liters, sizes.spirits); const people = Number($('#people').value); const hours = Number($('#hours').value); const title = `Ergebnis für ${people} Pers. · ${hours} Std · ${$('#intensity').selectedOptions[0].text} · ${$('#category').selectedOptions[0].text}`; $('#output').innerHTML = `
${title}
Richtwert – bitte an Zielgruppe & Saison anpassen

Ihr Kalkulator für die richtige Menge an Getränken für jeden Anlass

eta charset="utf-8" /> eta name="viewport" content="width=device-width, initial-scale=1" /> itle>Getränke-Kalkulator – Widget tyle> /* Fallback styles if Shadow DOM is not supported */ body { font-family: Inter, system-ui, -apple-system, Segoe UI, Roboto, Helvetica, Arial, "Apple Color Emoji", "Segoe UI Emoji"; background:#0b0c10; color:#e6e6e6; }
cript> (function(){ const mount = document.getElementById('drink-calculator-widget'); // Create Shadow DOM to avoid CSS conflicts const root = mount.attachShadow ? mount.attachShadow({mode:'open'}) : mount; // Utility: create elements const h = (tag, attrs = {}, children = []) => { const el = document.createElement(tag); for (const [k,v] of Object.entries(attrs)) { if (k === 'class') el.setAttribute('class', v); else if (k === 'style') el.setAttribute('style', v); else if (k.startsWith('on') && typeof v === 'function') el.addEventListener(k.substring(2), v); else el.setAttribute(k, v); } if (!Array.isArray(children)) children = [children]; children.filter(Boolean).forEach(c => el.append(c.nodeType ? c : document.createTextNode(String(c)))); return el; }; // Styles (scoped in Shadow Root) const style = h('style', {}, ` :host, .dcw * { box-sizing: border-box; } .dcw { --bg:#0b0c10; --panel:#11131a; --muted:#9aa0aa; --accent:#7dd3fc; --accent-2:#22d3ee; --border:#262b36; --ok:#22c55e; --warn:#f59e0b; --err:#ef4444; font-family: Inter, system-ui, -apple-system, Segoe UI, Roboto, Helvetica, Arial; color:#e6e6e6; } .card { background: linear-gradient(180deg, rgba(125,211,252,0.05), rgba(34,211,238,0.04)); border:1px solid var(--border); border-radius:16px; padding:16px; box-shadow: 0 10px 25px rgba(0,0,0,0.25); } .header { display:flex; align-items:center; justify-content:space-between; gap:8px; margin-bottom:12px; } .title { font-weight:700; font-size:18px; letter-spacing:0.2px; } .muted { color: var(--muted); font-size:12px; } .grid { display:grid; grid-template-columns: repeat(2, minmax(0,1fr)); gap:12px; } @media (min-width: 720px){ .grid{ grid-template-columns: repeat(4, minmax(0,1fr)); } } label { display:block; font-size:12px; color:var(--muted); margin:0 0 6px; } input[type="number"], select { width:100%; padding:10px 12px; background:#0f1218; color:#e6e6e6; border:1px solid var(--border); border-radius:12px; outline:none; transition:border .15s ease; } input[type="number"]:focus, select:focus { border-color: var(--accent); box-shadow: 0 0 0 3px rgba(125,211,252,0.2); } .row { display:flex; gap:8px; align-items:center; } .btn { appearance:none; border:1px solid var(--border); background:linear-gradient(180deg, #0f1218, #0b0e14); color:#e6e6e6; padding:10px 14px; border-radius:12px; cursor:pointer; font-weight:600; transition: transform .06s ease, box-shadow .2s ease, border .15s ease; } .btn:hover { border-color: var(--accent); box-shadow: 0 6px 16px rgba(34, 211, 238, 0.15); } .btn:active { transform: translateY(1px); } .btn.primary { background: linear-gradient(180deg, #0ea5e9, #06b6d4); color:#051018; border-color: transparent; } .btn.ghost { background: transparent; } .small { font-size:12px; } .out { margin-top:14px; } .table { width:100%; border-collapse: collapse; font-size:14px; } .table th, .table td { padding:10px 8px; border-bottom:1px solid var(--border); text-align:left; } .pill { display:inline-block; padding:4px 8px; border-radius:9999px; background:#0f1218; border:1px solid var(--border); font-size:12px; color:var(--muted); } .footer { display:flex; flex-wrap:wrap; gap:8px; justify-content:space-between; align-items:center; margin-top:10px; } details { background:#0f1218; border:1px solid var(--border); border-radius:12px; padding:10px 12px; } details summary { cursor:pointer; font-weight:600; color:#c7cbd3; } .tags { display:flex; gap:6px; flex-wrap:wrap; } .tag { cursor:pointer; } `); // HTML structure const container = h('div', { class: 'dcw card' }, [ h('div', { class: 'header' }, [ h('div', {}, [ h('div', { class: 'title' }, 'Getränke?Kalkulator'), h('div', { class: 'muted' }, 'Schnelle Mengenempfehlung für deine Feier – lokal auf deiner Seite, ohne externe Abhängigkeiten.') ]), h('div', { class:'pill' }, 'v1.0') ]), h('div', { class:'grid' }, [ // Personen h('div', {}, [ h('label', {}, 'Personenanzahl'), h('input', { id:'people', type:'number', min:'1', value:'25', inputmode:'numeric' }) ]), // Dauer h('div', {}, [ h('label', {}, 'Dauer (Stunden)'), h('input', { id:'hours', type:'number', min:'1', value:'5', step:'1' }) ]), // Art h('div', {}, [ h('label', {}, 'Art der Feier'), h('select', { id:'intensity' }, [ h('option', { value:'chill' }, 'Gemütlich'), h('option', { value:'normal', selected:'selected' }, 'Normal'), h('option', { value:'party' }, 'Party (feuchtfröhlich)') ]) ]), // Kategorie h('div', {}, [ h('label', {}, 'Getränkekategorie'), h('select', { id:'category' }, [ h('option', { value:'mixed', selected:'selected' }, 'Gemischt'), h('option', { value:'beer' }, 'Bier'), h('option', { value:'wine' }, 'Wein'), h('option', { value:'sparkling' }, 'Sekt/Prosecco'), h('option', { value:'soft' }, 'Softdrinks'), h('option', { value:'water' }, 'Wasser'), h('option', { value:'spirits' }, 'Longdrinks/Spirituosen') ]) ]) ]), h('details', { style:'margin-top:12px;' }, [ h('summary', {}, 'Erweiterte Optionen (Flaschengrößen & Verteilung)'), h('div', { style:'margin-top:10px;' }, [ h('div', { class:'grid' }, [ h('div', {}, [ h('label', {}, 'Bier Flaschengröße (l)'), h('input', { id:'beerSize', type:'number', step:'0.01', value:'0.33' }) ]), h('div', {}, [ h('label', {}, 'Wein/Sekt Flaschengröße (l)'), h('input', { id:'wineSize', type:'number', step:'0.01', value:'0.75' }) ]), h('div', {}, [ h('label', {}, 'Softdrinks Flaschengröße (l)'), h('input', { id:'softSize', type:'number', step:'0.1', value:'1.0' }) ]), h('div', {}, [ h('label', {}, 'Wasser Flaschengröße (l)'), h('input', { id:'waterSize', type:'number', step:'0.1', value:'1.0' }) ]) ]), h('div', { class:'muted', style:'margin:10px 0 6px;' }, 'Verteilung bei "Gemischt" (Summe 100%):'), h('div', { class:'grid' }, [ h('div', {}, [ h('label', {}, 'Bier %'), h('input', { id:'mixBeer', type:'number', min:'0', max:'100', step:'1', value:'35' }) ]), h('div', {}, [ h('label', {}, 'Wein %'), h('input', { id:'mixWine', type:'number', min:'0', max:'100', step:'1', value:'25' }) ]), h('div', {}, [ h('label', {}, 'Sekt %'), h('input', { id:'mixSpark', type:'number', min:'0', max:'100', step:'1', value:'5' }) ]), h('div', {}, [ h('label', {}, 'Softdrinks %'), h('input', { id:'mixSoft', type:'number', min:'0', max:'100', step:'1', value:'15' }) ]), h('div', {}, [ h('label', {}, 'Wasser %'), h('input', { id:'mixWater', type:'number', min:'0', max:'100', step:'1', value:'20' }) ]) ]) ]) ]), h('div', { class:'footer' }, [ h('div', { class:'tags muted small' }, [ h('span', { class:'pill tag', id:'preset-small' }, 'Schnell: 10 Pers.'), h('span', { class:'pill tag', id:'preset-mid' }, 'Schnell: 25 Pers.'), h('span', { class:'pill tag', id:'preset-big' }, 'Schnell: 60 Pers.') ]), h('div', { class:'row' }, [ h('button', { class:'btn ghost', id:'copy' }, 'Ergebnis kopieren'), h('button', { class:'btn primary', id:'calc' }, 'Berechnen') ]) ]), h('div', { class:'out', id:'output' }) ]); root.append(style, container); // Logic const $ = sel => root.querySelector(sel); const ratesPerHour = { beer: { chill: 0.15, normal: 0.25, party: 0.4 }, // Liter pro Person/Stunde wine: { chill: 0.10, normal: 0.15, party: 0.25 }, sparkling: { chill: 0.06, normal: 0.10, party: 0.16 }, soft: { chill: 0.12, normal: 0.20, party: 0.28 }, water: { chill: 0.18, normal: 0.25, party: 0.35 }, spirits: { chill: 0.04, normal: 0.08, party: 0.12 } // als Longdrink-Gesamtmenge (inkl. Mixer) in Litern }; const roundUp = (num, digits = 0) => { const p = Math.pow(10, digits); return Math.ceil(num * p) / p; }; function calc(){ const people = Math.max(1, Number($('#people').value || 0)); const hours = Math.max(1, Number($('#hours').value || 0)); const intensity = $('#intensity').value; // chill|normal|party const category = $('#category').value; // mixed|beer|wine|... const sizes = { beer: Number($('#beerSize').value || 0.33), wine: Number($('#wineSize').value || 0.75), sparkling: Number($('#wineSize').value || 0.75), soft: Number($('#softSize').value || 1.0), water: Number($('#waterSize').value || 1.0), spirits: 0.7 // feste Flaschengröße für Spirituosen }; let mix = { beer: Number($('#mixBeer').value||0)/100, wine: Number($('#mixWine').value||0)/100, sparkling: Number($('#mixSpark').value||0)/100, soft: Number($('#mixSoft').value||0)/100, water: Number($('#mixWater').value||0)/100 }; // Normalize mix if needed const sumMix = Object.values(mix).reduce((a,b)=>a+b,0); if (category === 'mixed' && sumMix > 0 && Math.abs(sumMix - 1) > 0.0001){ for (const k of Object.keys(mix)) mix[k] = mix[k] / sumMix; // rescale to 100% } // Calculate liters per category const res = {}; if (category === 'mixed') { // Total mixed beverage volume per person/hour = weighted sum of categories using their own rates const perHourTotal = mix.beer * ratesPerHour.beer[intensity] + mix.wine * ratesPerHour.wine[intensity] + mix.sparkling * ratesPerHour.sparkling[intensity] + mix.soft * ratesPerHour.soft[intensity] + mix.water * ratesPerHour.water[intensity]; const totalLiters = people * hours * perHourTotal; for (const k of ['beer','wine','sparkling','soft','water']){ const liters = totalLiters * mix[k]; res[k] = { liters }; } // Spirits are not included automatically in "Gemischt" } else if (category === 'spirits') { const liters = people * hours * ratesPerHour.spirits[intensity]; res.spirits = { liters }; } else { const liters = people * hours * ratesPerHour[category][intensity]; res[category] = { liters }; } // Build rows for output const rows = []; let shoppingLines = []; function pushRow(label, liters, sizeL, options={}){ const bottles = sizeL ? Math.ceil(liters / sizeL) : 0; let extra = ''; if (label === 'Bier'){ const crates = Math.ceil(bottles / 20); const kegs30 = Math.ceil(liters / 30); extra = `${crates} Kisten (à 20 Fl.) | optional: ${kegs30} × 30l-Fass`; } if (label === 'Wein' || label === 'Sekt/Prosecco'){ const glasses = Math.ceil(liters / 0.15); // 0.15l pro Glas Wein extra = `${glasses} Gläser (à ~0,15l)`; } if (label === 'Longdrinks/Spirituosen'){ // Spirits liters include mixer. Assume 40ml Spirit + 160ml Mixer pro Drink const drinks = Math.ceil(liters / 0.2); const spiritBottles = Math.ceil((drinks * 0.04) / 0.7); const mixerLiters = roundUp(drinks * 0.16, 1); extra = `${drinks} Longdrinks ? ${spiritBottles} × 0,7l Spirituosen + ${mixerLiters}l Mixer`; shoppingLines.push(`${spiritBottles} × 0,7l Spirituose(n)`); shoppingLines.push(`${mixerLiters}l Mixer (Tonic, Cola, etc.)`); rows.push(`
${label}${roundUp(liters,1)} l${extra}
${label}${roundUp(liters,1)} l${bottles} Flaschen à ${sizeL}l${extra}
${rows.join('')}
KategorieMenge (Liter)FlaschenHinweise
`; return `Getränke-Kalkulation: ${title}\n- ${shoppingLines.join("\n- ")}`; } // Events $('#calc').addEventListener('click', () => calc()); $('#copy').addEventListener('click', async () => { const text = calc(); try { await navigator.clipboard.writeText(text); const old = $('#copy').textContent; $('#copy').textContent = 'Kopiert ?'; setTimeout(()=> $('#copy').textContent = old, 1500); } catch(e){ alert('Konnte nicht in die Zwischenablage kopieren.'); } }); // Presets $('#preset-small').addEventListener('click', ()=>{ $('#people').value = 10; calc(); }); $('#preset-mid').addEventListener('click', ()=>{ $('#people').value = 25; calc(); }); $('#preset-big').addEventListener('click', ()=>{ $('#people').value = 60; calc(); }); // First render calc(); })();
Fragen zu unseren Leistungen? Sie erreichen uns telefonisch unter 0 68 94 - 27 20 oder senden Sie uns Ihre Anfrage:
Zum Kontaktformular