initial commit
Some checks failed
Build and Deploy / build (push) Has been cancelled

This commit is contained in:
DanielS
2026-09-20 22:48:46 +02:00
commit d8404ce857
8 changed files with 958 additions and 0 deletions

View File

@@ -0,0 +1,41 @@
name: Build and Deploy
on:
push:
branches:
- main
- staging
jobs:
build:
runs-on: webserver
container:
image: catthehacker/ubuntu:act-latest
steps:
- name: Code auschecken
uses: actions/checkout@v4
- name: Docker login to Gitea registry
run: echo "${{ secrets.REGISTRY_TOKEN }}" | docker login gitea.hephex.de -u "${{ secrets.REGISTRY_USER }}" --password-stdin
- name: Build Docker image
run: docker build -t gitea.hephex.de/daniel/getraenkekarte:latest -f Dockerfile .
- name: Push Docker image
run: docker push gitea.hephex.de/daniel/getraenkekarte:latest
- name: Clean up runner cache
run: |
docker image prune -f
docker builder prune -f
- name: Deploy to Proxmox LXC via SSH
uses: appleboy/ssh-action@v0.1.5
with:
host: 192.168.178.132
username: ${{ secrets.PROXMOX_USER }}
key: ${{ secrets.PROXMOX_SSH_KEY }}
script: |
cd /opt/getraenkekarte
docker compose pull
docker compose up -d

16
Dockerfile Normal file
View File

@@ -0,0 +1,16 @@
FROM caddy:2-alpine
RUN echo -e ":80 {\n\
root * /usr/share/caddy\n\
encode zstd gzip\n\
file_server\n\
header {\n\
Cache-Control \"public, max-age=3600\"\n\
X-Content-Type-Options nosniff\n\
}\n\
}" > /etc/caddy/Caddyfile
COPY index.html /usr/share/caddy/
COPY Getraenkekarte.pdf /usr/share/caddy/
EXPOSE 80

86
Getraenkekarte.pdf Normal file
View File

@@ -0,0 +1,86 @@
%PDF-1.4
%“Œ‹ž ReportLab Generated PDF document (opensource)
1 0 obj
<<
/F1 2 0 R /F2 3 0 R /F3 4 0 R /F4 5 0 R
>>
endobj
2 0 obj
<<
/BaseFont /Helvetica /Encoding /WinAnsiEncoding /Name /F1 /Subtype /Type1 /Type /Font
>>
endobj
3 0 obj
<<
/BaseFont /Helvetica-Bold /Encoding /WinAnsiEncoding /Name /F2 /Subtype /Type1 /Type /Font
>>
endobj
4 0 obj
<<
/BaseFont /ZapfDingbats /Name /F3 /Subtype /Type1 /Type /Font
>>
endobj
5 0 obj
<<
/BaseFont /Helvetica-Oblique /Encoding /WinAnsiEncoding /Name /F4 /Subtype /Type1 /Type /Font
>>
endobj
6 0 obj
<<
/Contents 10 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 9 0 R /Resources <<
/Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ]
>> /Rotate 0 /Trans <<
>>
/Type /Page
>>
endobj
7 0 obj
<<
/PageMode /UseNone /Pages 9 0 R /Type /Catalog
>>
endobj
8 0 obj
<<
/Author (\(anonymous\)) /CreationDate (D:20260920223817+02'00') /Creator (\(unspecified\)) /Keywords () /ModDate (D:20260920223817+02'00') /Producer (ReportLab PDF Library - \(opensource\))
/Subject (\(unspecified\)) /Title (\(anonymous\)) /Trapped /False
>>
endobj
9 0 obj
<<
/Count 1 /Kids [ 6 0 R ] /Type /Pages
>>
endobj
10 0 obj
<<
/Filter [ /ASCII85Decode /FlateDecode ] /Length 1640
>>
stream
GauHL>Bf'b&:WeD9HUj$m/bbKpsuoZ82a2Jkm"_G:(Ju^"=P*K/">ZH^V1q&Cd[QBB$!AqD)B\"^2InFJq\-3r?!ZnNX,(N)$S/j0Eiq^JADum#-I>GRS2A!E*I8kXs8a^[l=nR$+6`#:tWJH=UWiWKc438M(0@H9EfKr!m3LmQt>=Q@"P/$CU>+1KYcKN8SpHU%;psV&t^h(QUeN;*oq?g9cs9;h/0j8bqJjpgT'bC>NONGG-AM^jm0#UTN6docaN*u`+E>YZ@/TM17lD4C*^2dWD"Ik?m7HJ#9&3E'RD5PRJiPe>Eb]4/*r8/go]4EA]&<L132"/YajF)bmrCGAtpm>r(m7G[>;jPGB'O@k:kKl_PiI'E-mV_&$77L]EHtUO)Q'\+%#1(`mquK*.lJp)tW=u/@uHY]PTs6lMqO@'mA_C^1W9L]\1;OD6lOg%FsX!2f*mOrJU9n7t\QpHZ4"HE]H+j\E\!OYB(,1EJNM4W#5@<d,fW[W,(LaZQ+A'Y^>3^*%NpK=gUm0>fXrGIXp`a-l_PBIGA/pgKkTi1@%iLL5LOp^6g+\q4F6Eqk$k,Ub_ck#EE\Tg@-\c/:n@*1FGYi]i%LkU1b05dghnKBP'A09&80ff"P24e'iqK1\ae(hZmR>f5>JZ.Yb=V,qck>`etc.rUE"se*b,8]0\`]=U1bJD2BUD_G>3U<Ji#s&K57;i_[H`7\7N3#.k#QR58M4@ePeN)oRjWn"KG\Lq*qH,frVDF#n)Pi#@R>:5M&mX3hl:5K.2F-tbi1b$<O"^D\k$Xf-9iJWW8&3o_?S7tkTMa^^PlKOM`e#LNq'T[P+S#7(r[K&f\'nI)@%pH?A\WZgOXic)M5(1@7k"@h@3$^#%CX>*;2?JUrfZ5lR9HbGlhn,\Z;qZ$/0UuQ$JB%dns=h86DL)?Jc<,!5``\+etU`>+)6/Z92$IB_^\iFmJ>(6`DQ1Q6Y,Ru?8Xaul;l"qT.QoN1ZGMli-;]VqnT)K(=qUdq?<Z"A27aZt[HH.V+Orr]#-LfRHE]DH4KTW5U?OBI+rCTYT5PP&"dTBkJ1\0+=G(aufP4PLn6jU^o<9&8U,Vhp;h@pa!*,.:r(52&e-&3Y`+jaSp.!gPVQ&b%2X7^5;iV#RIfb@B/+daaT%e>"#cDtLNEhp?"5XL;qU_k,1G^1Cj@b<)u>hR@/b9@4%X^j9-cFL#1VclNIkPR.pUUGk+)7Gl+c)C-e6JuK6UDC+`L$MGT$H)Sbe`G&RS#`mMhSo!El[>a??H)'?qbdIM4+u47<I0Bocmr*4[I')IBW\V4<GJMg/ti_W!e3ngj=EcUNO#ikkt^2)+]VHSlV+4:7tftG$EkZ>D63$[@oLntm=fj9C(R1g0*J,/9Su2S4%]1c5fV*XkdN8Y<)@C#MfV?MlM1ZOlVkH\b5a'"Yq%=:YA=+LT^%$_Pf6kYGArsc,$\"l$hO6BWU&R;8l:sqLeW<,0h$)s'L6b/Np=otnU/2,_8R$R*:?m'@Od"!]%WV$L6FXGTDXjZ+cTp-AWXdIUuDLYbgj$ZSm[s'8JE[MBjP(+47h+1VuZ.;,70YV8RMb`_@]Og@rnHt@kP8tI_;?$I9OS6jO$nBh\3Z8YrS[if0ai8+calhq(F=5r<Had[]K~>endstream
endobj
xref
0 11
0000000000 65535 f
0000000061 00000 n
0000000122 00000 n
0000000229 00000 n
0000000341 00000 n
0000000424 00000 n
0000000539 00000 n
0000000743 00000 n
0000000811 00000 n
0000001091 00000 n
0000001150 00000 n
trailer
<<
/ID
[<c74df38e59f13fa69b76e16abbe7b5c1><c74df38e59f13fa69b76e16abbe7b5c1>]
% ReportLab generated PDF document -- digest (opensource)
/Info 8 0 R
/Root 7 0 R
/Size 11
>>
startxref
2882
%%EOF

View File

@@ -0,0 +1,86 @@
%PDF-1.4
%“Œ‹ž ReportLab Generated PDF document (opensource)
1 0 obj
<<
/F1 2 0 R /F2 3 0 R /F3 4 0 R /F4 5 0 R
>>
endobj
2 0 obj
<<
/BaseFont /Helvetica /Encoding /WinAnsiEncoding /Name /F1 /Subtype /Type1 /Type /Font
>>
endobj
3 0 obj
<<
/BaseFont /Helvetica-Bold /Encoding /WinAnsiEncoding /Name /F2 /Subtype /Type1 /Type /Font
>>
endobj
4 0 obj
<<
/BaseFont /ZapfDingbats /Name /F3 /Subtype /Type1 /Type /Font
>>
endobj
5 0 obj
<<
/BaseFont /Helvetica-Oblique /Encoding /WinAnsiEncoding /Name /F4 /Subtype /Type1 /Type /Font
>>
endobj
6 0 obj
<<
/Contents 10 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 9 0 R /Resources <<
/Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ]
>> /Rotate 0 /Trans <<
>>
/Type /Page
>>
endobj
7 0 obj
<<
/PageMode /UseNone /Pages 9 0 R /Type /Catalog
>>
endobj
8 0 obj
<<
/Author (\(anonymous\)) /CreationDate (D:20260920223503+02'00') /Creator (\(unspecified\)) /Keywords () /ModDate (D:20260920223503+02'00') /Producer (ReportLab PDF Library - \(opensource\))
/Subject (\(unspecified\)) /Title (\(anonymous\)) /Trapped /False
>>
endobj
9 0 obj
<<
/Count 1 /Kids [ 6 0 R ] /Type /Pages
>>
endobj
10 0 obj
<<
/Filter [ /ASCII85Decode /FlateDecode ] /Length 1719
>>
stream
GauHL=``:f&:WeDFC%jU$ac?if=kYu+6t-j;!b26?3CZj5tK9l`"i=Km1DYt=L)(b"H8J1eo^Z\od(2(nP-=hP81li%tC/_+;F_k&8lIVYG(Eo^9pKaBb>u#S2"u!gT^/YYJXq(R)H<;m!l']$hkp#)Vf:c.O\+lX.Yj^7Lb,,DWA;m`Ds@Qg5\@Is7P&6D)h"]K+Tp8m8a1d2t6\uU=94e1iVR;bJ54r]lV8u4_RLg&*WH8K!'UCGFeW0VrBn`?EjICmloL9c[fVA$.EWPDHMq2<S>*Q@CV7t.hP&Y_,MgB$.M'#KqX%GGd:!F)(+i$e.a3@8g]`*"R?rtAHI]bhka/KOnkpRg"lRo5MXuh_n:jkB"#@W4q!1+\MOhPMGH-4g*a!QO-@?Ko<i/>N%bL!Y[*_Z()W9<GR/qC>^gKXfu5IP$gk9;%o5M/B#`B=9jIi'b1#M'$^a[4J:(Ih&B>!-;hnR[3-qaLS+rZ2LpsaD3a/QHQ"\kH)8=l9qh%)&IQG15H^E@?Mp(^MC]*tF/c9b]@o?o;4Kp@0^4LQS]a_n7F!"*q?OlFPn,#W`+"NhhM#fPT15R+3AfZauHVklk2YqSU7G@CJKPV3pi9DCraE.?Yk0X*OSHc'LrlXaU>G3t1a4"VHahno^r*$6kMP<Zr907)FUUcD3+]N)i>5LcY:J[$<cJa1#rXaa^fL3=eWYj/J(V',fQn3%&%k!9#c+8r\k&Bu=k8b*`[j@K[)F)>rOt!ONNR1L[)E-Q]AE5c;)mE!)RlQ*Z2729)S0(7AEe)kN6HiFH,Y:`<Ra]ql"8=4H3[O4(0#ql1rZc;2689"F<91WVp_-\G)c5Y+"(R/p<5q5:Ll08AP:%cX#oa8[#bi-&_4X6TO,tV\-coGX`\492S6qC"6B2n(&;S)J<MTrb'GuTM`d+$#Z,%]JCAguka_iR;+4PTd_FI!tW;k1F:W9@Wc*Sk0%s?3O#VeDL-.=Vr[9_dR9K<S7gjmlH35B2IX6.i1B`/q[<Q^*bdUAu\2%YtD]e+pNSHkS^%Xc<GYC\Xodm&CUIrmmZCJ6!"U1d2EIGbmIb>3+d)/uKh3Lm)l_TYtD?:mlZf<pc.Iie@S['@A.BB62VXG;3R&rW#%KQG'pP`nO;(G\P.h@u9L(b7W8(5*]i--%1K2IO%Z;=jrcA3*l+Y1B`6L07%*B%p"aL1$tl.`gof#-Sa"bF.q0":55EO^`Ll,lJ;6B(2&8b&5d4Q9c?<.AE4CZKs7eQ&M$Tq.Z?j/V:G3'W90PR?Y<i+n3*UdbaZIVi+@&B7p1p+&Dh6i3qfUhXteqe@s$0e`#`0lN8VLB#XOt#?22W4\#5'8N"P&k`tk"g((&0Uc)u6.SWq0p<n\9JTk7<0on&0UTFJq``.1i8C_h;3n&rQ)VjtFKi_.N[T3hZE4TdZqa*I)2$ah<&;!5<]%3R`^$>K(7cT;/%,P(u.O[3M`ULUs-*DG;ZnC@'=9[?W[9Zq=G[9pe!*+N<;g*.\5K[Q2M/Wch/G4ut;E)lA<3*MeP^#r5X^YTcJEZPDe\1Fkk8@S4/hr4Ag(kA5F"1rog"O!2%AsSE5C!LIoaD3b:,Ee)M=.4-Sk,-\=jV:1iseq*Nj1L-Z-L5C(^I3fj[5V@<U!!t3sHJI^$rghAe-GkCG9XI]0*;7P3l-P*7rp"bUX+!QJlBF(cRcDE`O5`=Ahl67<up3Cld`LT3K\=&#o'H3<~>endstream
endobj
xref
0 11
0000000000 65535 f
0000000061 00000 n
0000000122 00000 n
0000000229 00000 n
0000000341 00000 n
0000000424 00000 n
0000000539 00000 n
0000000743 00000 n
0000000811 00000 n
0000001091 00000 n
0000001150 00000 n
trailer
<<
/ID
[<d217652d06a40a581f105adac8227bc7><d217652d06a40a581f105adac8227bc7>]
% ReportLab generated PDF document -- digest (opensource)
/Info 8 0 R
/Root 7 0 R
/Size 11
>>
startxref
2961
%%EOF

187
create_pdf.py Normal file
View File

@@ -0,0 +1,187 @@
import os
from reportlab.lib.pagesizes import A4
from reportlab.lib import colors
from reportlab.lib.units import mm
from reportlab.platypus import SimpleDocTemplate, Paragraph, Spacer, Table, TableStyle
from reportlab.lib.styles import getSampleStyleSheet, ParagraphStyle
from reportlab.pdfgen import canvas
class NumberedCanvas(canvas.Canvas):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self._saved_page_states = []
def showPage(self):
self._saved_page_states.append(dict(self.__dict__))
self._startPage()
def save(self):
num_pages = len(self._saved_page_states)
for state in self._saved_page_states:
self.__dict__.update(state)
self.draw_page_decorations()
super().showPage()
super().save()
def draw_page_decorations(self):
self.saveState()
self.setStrokeColor(colors.HexColor("#D4AF37"))
self.setLineWidth(2)
self.rect(10*mm, 10*mm, 190*mm, 277*mm)
self.setLineWidth(0.7)
self.rect(11.5*mm, 11.5*mm, 187*mm, 274*mm)
self.restoreState()
def generate_pdf(filename):
doc = SimpleDocTemplate(
filename,
pagesize=A4,
leftMargin=16*mm,
rightMargin=16*mm,
topMargin=16*mm,
bottomMargin=16*mm
)
styles = getSampleStyleSheet()
title_style = ParagraphStyle(
'MainTitle',
fontName='Helvetica-Bold',
fontSize=22,
leading=26,
alignment=1,
textColor=colors.HexColor("#1A1A1A"),
spaceAfter=3
)
subtitle_style = ParagraphStyle(
'SubTitle',
fontName='Helvetica-Oblique',
fontSize=10,
leading=13,
alignment=1,
textColor=colors.HexColor("#555555"),
spaceAfter=10
)
section_style = ParagraphStyle(
'SectionHeader',
fontName='Helvetica-Bold',
fontSize=12,
leading=15,
textColor=colors.HexColor("#8A6D1C"),
spaceBefore=6,
spaceAfter=6,
alignment=0
)
drink_title_style = ParagraphStyle(
'DrinkTitle',
fontName='Helvetica-Bold',
fontSize=10,
leading=12,
textColor=colors.HexColor("#111111"),
spaceAfter=2
)
drink_text_style = ParagraphStyle(
'DrinkText',
fontName='Helvetica',
fontSize=8.5,
leading=11,
textColor=colors.HexColor("#333333")
)
footer_style = ParagraphStyle(
'Footer',
fontName='Helvetica-Oblique',
fontSize=9,
leading=12,
alignment=1,
textColor=colors.HexColor("#777777"),
spaceBefore=8
)
story = []
# Header
story.append(Paragraph("🍸 GETRÄNKEKARTE 🍸", title_style))
story.append(Paragraph("Frisch zubereitet an der Bar auf Eis.", subtitle_style))
# Line
line_table = Table([[""]], colWidths=[178*mm], rowHeights=[1])
line_table.setStyle(TableStyle([('LINEABOVE', (0,0), (-1,-1), 1, colors.HexColor("#D4AF37"))]))
story.append(line_table)
story.append(Spacer(1, 4*mm))
# Cocktails
story.append(Paragraph("🍹 SIGNATURE COCKTAILS", section_style))
cocktails = [
("1. Moscow Mule", "<b>Zutaten:</b> Wodka, frischer Limettensaft, Ginger Beer, Minzzweig & Limettenspalte.<br/><b>Geschmack:</b> Scharf-würzig, erfrischend und spritzig."),
("2. Gin & Tonic", "<b>Zutaten:</b> Klassischer Gin, Tonic Water, Limettenscheibe.<br/><b>Geschmack:</b> Der elegante Klassiker – herb, bitter und ohne Zuckerüberhang."),
("3. Mojito", "<b>Zutaten:</b> Weißer Rum, frische Minzblätter, Zuckersirup, Limettensaft, Sprudelwasser.<br/><b>Geschmack:</b> Aromatisches Bar-Feeling mit frischer Minze."),
("4. Cuba Libre", "<b>Zutaten:</b> Weißer Rum, erfrischende Cola, frischer Limettensaft, Limette.<br/><b>Geschmack:</b> Der süße, vertraute Party-Dauerbrenner."),
("5. Vodka Cranberry", "<b>Zutaten:</b> Wodka, Cranberrysaft, Soda, frischer Limettensaft, Limettenscheibe.<br/><b>Geschmack:</b> Angenehm säuerlich-herb statt klebrig-süß."),
("6. Skinny Bitch", "<b>Zutaten:</b> Wodka, spritziges Mineralwasser, viel frischer Limettensaft.<br/><b>Geschmack:</b> Der leichte, komplett zucker- und kalorienfreie Drink.")
]
col_width = 87 * mm
table_data = []
for i in range(0, len(cocktails), 2):
cell_left = [
Paragraph(cocktails[i][0], drink_title_style),
Paragraph(cocktails[i][1], drink_text_style)
]
cell_right = [
Paragraph(cocktails[i+1][0], drink_title_style),
Paragraph(cocktails[i+1][1], drink_text_style)
]
table_data.append([cell_left, cell_right])
cocktail_table = Table(table_data, colWidths=[col_width, col_width])
cocktail_table.setStyle(TableStyle([
('VALIGN', (0,0), (-1,-1), 'TOP'),
('BOTTOMPADDING', (0,0), (-1,-1), 8),
('RIGHTPADDING', (0,0), (0,-1), 6),
('LEFTPADDING', (1,0), (1,-1), 6),
]))
story.append(cocktail_table)
story.append(Spacer(1, 2*mm))
story.append(Paragraph("🍃 0.0% MOCKTAILS (ALKOHOLFREI)", section_style))
mocktails = [
("Virgin Mojito", "Frische Minze, Zuckersirup, Limettensaft, aufgegossen mit Ginger Beer & Sprudelwasser."),
("Cranberry Ginger Splash", "Feinherber Cranberrysaft, frischer Limettensaft & würziges Ginger Beer."),
("Homemade Lime Soda", "Frischer Limettensaft, süßer Zuckersirup, Minze & eiskaltes Sprudelwasser.")
]
m_data = []
m_col_width = 58 * mm
row_cells = []
for m in mocktails:
cell = [
Paragraph(f"<b>{m[0]}</b>", drink_title_style),
Paragraph(m[1], drink_text_style)
]
row_cells.append(cell)
m_data.append(row_cells)
mocktail_table = Table(m_data, colWidths=[m_col_width, m_col_width, m_col_width])
mocktail_table.setStyle(TableStyle([
('VALIGN', (0,0), (-1,-1), 'TOP'),
('RIGHTPADDING', (0,0), (-1,-1), 4),
('LEFTPADDING', (0,0), (-1,-1), 4),
]))
story.append(mocktail_table)
story.append(Spacer(1, 6*mm))
story.append(Paragraph("✨ Cheers! Cheers to great drinks and good vibes! ✨", footer_style))
doc.build(story, canvasmaker=NumberedCanvas)
print("PDF updated.")
if __name__ == "__main__":
out_path = r"C:\Users\Danie\.gemini\antigravity-ide\scratch\Getraenkekarte.pdf"
generate_pdf(out_path)

7
docker-compose.yml Normal file
View File

@@ -0,0 +1,7 @@
services:
getraenkekarte:
image: gitea.hephex.de/daniel/getraenkekarte:latest
container_name: getraenkekarte
restart: unless-stopped
ports:
- "8085:80"

187
getraenkekarte.html Normal file
View File

@@ -0,0 +1,187 @@
<!DOCTYPE html>
<html lang="de">
<head>
<meta charset="UTF-8">
<style>
@page {
size: A4 portrait;
margin: 15mm;
}
* {
box-sizing: border-box;
margin: 0;
padding: 0;
}
body {
font-family: 'Georgia', serif;
background-color: #0d1117;
color: #e6edf3;
padding: 24px;
border: 3px double #d4af37;
border-radius: 8px;
height: calc(100vh - 30mm);
display: flex;
flex-direction: column;
justify-content: space-between;
}
.header {
text-align: center;
border-bottom: 1px solid #d4af37;
padding-bottom: 12px;
margin-bottom: 14px;
}
.header h1 {
font-size: 26px;
letter-spacing: 3px;
text-transform: uppercase;
color: #d4af37;
margin-bottom: 6px;
}
.header p {
font-size: 13px;
font-style: italic;
color: #8b949e;
}
.section-title {
font-size: 15px;
letter-spacing: 2px;
text-transform: uppercase;
color: #d4af37;
border-bottom: 1px dashed rgba(212, 175, 55, 0.4);
padding-bottom: 4px;
margin-top: 10px;
margin-bottom: 10px;
}
.grid {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 12px 18px;
}
.drink {
background: rgba(255, 255, 255, 0.03);
border: 1px solid rgba(212, 175, 55, 0.2);
border-radius: 6px;
padding: 8px 10px;
}
.drink-title {
font-size: 14px;
font-weight: bold;
color: #f0e6d2;
margin-bottom: 4px;
}
.drink-desc {
font-size: 11px;
line-height: 1.4;
color: #c9d1d9;
}
.drink-desc strong {
color: #d4af37;
}
.mocktails-grid {
display: grid;
grid-template-columns: 1fr 1fr 1fr;
gap: 10px;
}
.footer {
text-align: center;
font-size: 11px;
color: #8b949e;
border-top: 1px solid rgba(212, 175, 55, 0.3);
padding-top: 8px;
margin-top: 10px;
}
@media print {
body {
background-color: #111 !important;
-webkit-print-color-adjust: exact;
print-color-adjust: exact;
}
}
</style>
</head>
<body>
<div class="header">
<h1>🍸 GETRÄNKEKARTE 🍸</h1>
<p>50. Geburtstag — Frisch zubereitet an der Bar auf Eis</p>
</div>
<div>
<div class="section-title">🍹 Cocktail-Highlights</div>
<div class="grid">
<div class="drink">
<div class="drink-title">1. Moscow Mule</div>
<div class="drink-desc">
<strong>Zutaten:</strong> Wodka, Limettensaft, Ginger Beer, Minze & Limette.<br>
<strong>Geschmack:</strong> Scharf-würzig, erfrischend & spritzig.
</div>
</div>
<div class="drink">
<div class="drink-title">2. Gin & Tonic</div>
<div class="drink-desc">
<strong>Zutaten:</strong> Gin, Tonic Water, Limettenscheibe.<br>
<strong>Geschmack:</strong> Eleganter Klassiker – herb, bitter & rein.
</div>
</div>
<div class="drink">
<div class="drink-title">3. Mojito</div>
<div class="drink-desc">
<strong>Zutaten:</strong> Weißer Rum, frische Minze, Zuckersirup, Limettensaft, Soda.<br>
<strong>Geschmack:</strong> Aromatisches Bar-Feeling mit frischer Minze.
</div>
</div>
<div class="drink">
<div class="drink-title">4. Cuba Libre</div>
<div class="drink-desc">
<strong>Zutaten:</strong> Weißer Rum, Cola, frischer Limettensaft, Limettenspalte.<br>
<strong>Geschmack:</strong> Süßer & vertrauter Party-Klassiker.
</div>
</div>
<div class="drink">
<div class="drink-title">5. Vodka Cranberry</div>
<div class="drink-desc">
<strong>Zutaten:</strong> Wodka, Cranberrysaft, Soda, frischer Limettensaft.<br>
<strong>Geschmack:</strong> Fruchtig-rot, angenehm herb & säuerlich.
</div>
</div>
<div class="drink">
<div class="drink-title">6. Skinny Bitch</div>
<div class="drink-desc">
<strong>Zutaten:</strong> Wodka, Mineralwasser, viel frischer Limettensaft.<br>
<strong>Geschmack:</strong> Leicht, frisch, zucker- & kalorienfrei.
</div>
</div>
</div>
</div>
<div>
<div class="section-title">🍃 Alkoholfreie Mocktails</div>
<div class="mocktails-grid">
<div class="drink">
<div class="drink-title">Virgin Mojito</div>
<div class="drink-desc">Frische Minze, Limettensaft, Zuckersirup, Ginger Beer & Sprudel.</div>
</div>
<div class="drink">
<div class="drink-title">Cranberry Ginger Splash</div>
<div class="drink-desc">Cranberrysaft, frischer Limettensaft & würziges Ginger Beer.</div>
</div>
<div class="drink">
<div class="drink-title">Homemade Lime Soda</div>
<div class="drink-desc">Frischer Limettensaft, Zuckersirup, aromatische Minze & Eiswasser.</div>
</div>
</div>
</div>
<div class="footer">
Cheers! Auf unvergessliche Momente und einen tollen Abend! ✨
</div>
</body>
</html>

348
index.html Normal file
View File

@@ -0,0 +1,348 @@
<!DOCTYPE html>
<html lang="de">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>BAR & COCKTAILS</title>
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Plus+Jakarta+Sans:wght@400;600;700;800&family=Space+Grotesk:wght@500;700&display=swap" rel="stylesheet">
<style>
:root {
--bg: #090b10;
--card-bg: rgba(22, 27, 34, 0.75);
--card-border: rgba(255, 255, 255, 0.08);
--primary: #f59e0b;
--primary-glow: rgba(245, 158, 11, 0.25);
--accent: #ec4899;
--accent-glow: rgba(236, 72, 153, 0.25);
--text: #f8fafc;
--text-muted: #94a3b8;
--tag-bg: rgba(245, 158, 11, 0.12);
}
* {
box-sizing: border-box;
margin: 0;
padding: 0;
-webkit-tap-highlight-color: transparent;
}
body {
font-family: 'Plus Jakarta Sans', -apple-system, sans-serif;
background-color: var(--bg);
color: var(--text);
min-height: 100vh;
display: flex;
justify-content: center;
padding: 20px 16px 40px;
position: relative;
overflow-x: hidden;
}
/* Ambient Glow */
body::before {
content: "";
position: fixed;
top: -100px;
left: 50%;
transform: translateX(-50%);
width: 400px;
height: 400px;
background: radial-gradient(circle, var(--accent-glow) 0%, var(--primary-glow) 50%, transparent 70%);
filter: blur(80px);
z-index: 0;
pointer-events: none;
}
.container {
width: 100%;
max-width: 480px;
position: relative;
z-index: 1;
display: flex;
flex-direction: column;
gap: 24px;
}
header {
text-align: center;
padding: 20px 0 10px;
}
.badge {
display: inline-flex;
align-items: center;
gap: 6px;
padding: 6px 14px;
border-radius: 999px;
background: rgba(255, 255, 255, 0.05);
border: 1px solid rgba(255, 255, 255, 0.1);
font-size: 11px;
font-weight: 700;
letter-spacing: 1.5px;
text-transform: uppercase;
color: var(--primary);
margin-bottom: 12px;
backdrop-filter: blur(10px);
}
h1 {
font-family: 'Space Grotesk', sans-serif;
font-size: 32px;
font-weight: 700;
letter-spacing: -0.5px;
background: linear-gradient(135deg, #fff 30%, #cbd5e1 100%);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
margin-bottom: 8px;
}
header p {
font-size: 13px;
color: var(--text-muted);
line-height: 1.5;
}
.section-title {
font-family: 'Space Grotesk', sans-serif;
font-size: 14px;
font-weight: 700;
letter-spacing: 1.5px;
text-transform: uppercase;
color: var(--primary);
display: flex;
align-items: center;
gap: 8px;
margin-bottom: 12px;
}
.section-title::after {
content: "";
flex: 1;
height: 1px;
background: linear-gradient(90deg, var(--card-border), transparent);
}
.menu-grid {
display: flex;
flex-direction: column;
gap: 12px;
}
.card {
background: var(--card-bg);
border: 1px solid var(--card-border);
border-radius: 16px;
padding: 16px;
backdrop-filter: blur(16px);
transition: transform 0.2s ease, border-color 0.2s ease, box-shadow 0.2s ease;
position: relative;
overflow: hidden;
}
.card:active {
transform: scale(0.985);
}
.card-top {
display: flex;
justify-content: space-between;
align-items: flex-start;
margin-bottom: 8px;
}
.card-name {
font-size: 16px;
font-weight: 700;
color: #fff;
}
.card-icon {
font-size: 18px;
}
.card-ingredients {
font-size: 12.5px;
color: #cbd5e1;
line-height: 1.45;
margin-bottom: 10px;
}
.card-footer {
display: flex;
align-items: center;
gap: 6px;
}
.taste-tag {
display: inline-block;
font-size: 11px;
font-weight: 600;
color: var(--primary);
background: var(--tag-bg);
padding: 4px 10px;
border-radius: 8px;
border: 1px solid rgba(245, 158, 11, 0.2);
}
.taste-tag.green {
color: #34d399;
background: rgba(52, 211, 153, 0.12);
border-color: rgba(52, 211, 153, 0.2);
}
footer {
text-align: center;
padding-top: 16px;
font-size: 12px;
color: var(--text-muted);
}
@media print {
body {
background: #fff;
color: #000;
}
.card {
border: 1px solid #ddd;
background: #fff;
}
h1, .card-name {
color: #000;
-webkit-text-fill-color: initial;
}
}
</style>
</head>
<body>
<div class="container">
<header>
<div class="badge">🔥 Open Bar</div>
<h1>GETRÄNKEKARTE</h1>
<p>Frisch im Glas zubereitet. Wähle deinen Drink!</p>
</header>
<!-- Cocktails -->
<section>
<div class="section-title">🍹 Signature Cocktails</div>
<div class="menu-grid">
<div class="card">
<div class="card-top">
<span class="card-name">Moscow Mule</span>
<span class="card-icon">🥒</span>
</div>
<p class="card-ingredients">Wodka, frischer Limettensaft, Ginger Beer, Minzzweig & Limettenspalte</p>
<div class="card-footer">
<span class="taste-tag">Scharf-würzig & erfrischend</span>
</div>
</div>
<div class="card">
<div class="card-top">
<span class="card-name">Gin & Tonic</span>
<span class="card-icon">🍋</span>
</div>
<p class="card-ingredients">Klassischer Gin, Tonic Water, angedrückte Limettenscheibe</p>
<div class="card-footer">
<span class="taste-tag">Herb, bitter & puristisch</span>
</div>
</div>
<div class="card">
<div class="card-top">
<span class="card-name">Mojito</span>
<span class="card-icon">🌿</span>
</div>
<p class="card-ingredients">Weißer Rum, frische Minzblätter, Zuckersirup, Limettensaft, Soda</p>
<div class="card-footer">
<span class="taste-tag">Aromatisch & minzfrisch</span>
</div>
</div>
<div class="card">
<div class="card-top">
<span class="card-name">Cuba Libre</span>
<span class="card-icon">🥃</span>
</div>
<p class="card-ingredients">Weißer Rum, Cola, frischer Limettensaft, Limettenspalte</p>
<div class="card-footer">
<span class="taste-tag">Süß & party-ready</span>
</div>
</div>
<div class="card">
<div class="card-top">
<span class="card-name">Vodka Cranberry</span>
<span class="card-icon">🍒</span>
</div>
<p class="card-ingredients">Wodka, feinherber Cranberrysaft, Soda, frischer Limettensaft</p>
<div class="card-footer">
<span class="taste-tag">Fruchtig & säuerlich-herb</span>
</div>
</div>
<div class="card">
<div class="card-top">
<span class="card-name">Skinny Bitch</span>
<span class="card-icon">⚡</span>
</div>
<p class="card-ingredients">Wodka, spritziges Mineralwasser, viel frischer Limettensaft</p>
<div class="card-footer">
<span class="taste-tag">0% Zucker & ultraleicht</span>
</div>
</div>
</div>
</section>
<!-- Mocktails -->
<section>
<div class="section-title">🍃 0.0% Mocktails</div>
<div class="menu-grid">
<div class="card">
<div class="card-top">
<span class="card-name">Virgin Mojito</span>
<span class="card-icon">🌱</span>
</div>
<p class="card-ingredients">Frische Minze, Limettensaft, Zuckersirup, Ginger Beer & Sprudel</p>
<div class="card-footer">
<span class="taste-tag green">Alkoholfrei & prickelnd</span>
</div>
</div>
<div class="card">
<div class="card-top">
<span class="card-name">Cranberry Ginger Splash</span>
<span class="card-icon">🍓</span>
</div>
<p class="card-ingredients">Cranberrysaft, frischer Limettensaft, Ginger Beer</p>
<div class="card-footer">
<span class="taste-tag green">Fruchtig & feinherb</span>
</div>
</div>
<div class="card">
<div class="card-top">
<span class="card-name">Homemade Lime Soda</span>
<span class="card-icon">🍋</span>
</div>
<p class="card-ingredients">Frischer Limettensaft, Zuckersirup, Minze, Eiswasser</p>
<div class="card-footer">
<span class="taste-tag green">Zitruskick & eiskalt</span>
</div>
</div>
</div>
</section>
<footer>
Cheers! Let's celebrate 🎉
</footer>
</div>
</body>
</html>