make main a version off dev
24
.gitignore
vendored
Normal file
@ -0,0 +1,24 @@
|
||||
# build output
|
||||
dist/
|
||||
|
||||
# generated types
|
||||
.astro/
|
||||
|
||||
# dependencies
|
||||
node_modules/
|
||||
|
||||
# logs
|
||||
npm-debug.log*
|
||||
yarn-debug.log*
|
||||
yarn-error.log*
|
||||
pnpm-debug.log*
|
||||
|
||||
# environment variables
|
||||
.env
|
||||
.env.production
|
||||
|
||||
# macOS-specific files
|
||||
.DS_Store
|
||||
|
||||
# jetbrains setting folder
|
||||
.idea/
|
||||
4
.vscode/extensions.json
vendored
Normal file
@ -0,0 +1,4 @@
|
||||
{
|
||||
"recommendations": ["astro-build.astro-vscode"],
|
||||
"unwantedRecommendations": []
|
||||
}
|
||||
11
.vscode/launch.json
vendored
Normal file
@ -0,0 +1,11 @@
|
||||
{
|
||||
"version": "0.2.0",
|
||||
"configurations": [
|
||||
{
|
||||
"command": "./node_modules/.bin/astro dev",
|
||||
"name": "Development server",
|
||||
"request": "launch",
|
||||
"type": "node-terminal"
|
||||
}
|
||||
]
|
||||
}
|
||||
@ -1,18 +1,26 @@
|
||||
name: deploy
|
||||
|
||||
steps:
|
||||
deploy:
|
||||
image: node:20
|
||||
environment:
|
||||
FLY_API_TOKEN:
|
||||
from_secret: FLY_API_TOKEN
|
||||
pipeline:
|
||||
build:
|
||||
image: node:20-alpine
|
||||
commands:
|
||||
- curl -L https://fly.io/install.sh | sh
|
||||
- export PATH="$HOME/.fly/bin:$PATH"
|
||||
- flyctl deploy --config fly.toml --app gallus-pub
|
||||
- npm ci
|
||||
- npm run build
|
||||
when:
|
||||
branch: main
|
||||
event: [push, pull_request]
|
||||
deploy:
|
||||
depends_on: [build]
|
||||
image: flyio/flyctl:latest
|
||||
secrets: [fly_api_token]
|
||||
commands:
|
||||
- flyctl deploy --remote-only
|
||||
when:
|
||||
branch: main
|
||||
event: push
|
||||
|
||||
when:
|
||||
branch:
|
||||
- main
|
||||
event:
|
||||
- push
|
||||
branches:
|
||||
include: [main, dev]
|
||||
|
||||
cache:
|
||||
mount:
|
||||
- node_modules
|
||||
- .npm
|
||||
35
Dockerfile
@ -1,18 +1,25 @@
|
||||
FROM nginx:alpine
|
||||
FROM node:20-alpine AS build
|
||||
|
||||
# Kopiere statische Dateien ins Nginx-Verzeichnis
|
||||
COPY src/ /usr/share/nginx/html/
|
||||
WORKDIR /app
|
||||
|
||||
# Konfiguriere NGINX für Single-Page-Applications (optional)
|
||||
RUN echo 'server { \
|
||||
listen 80; \
|
||||
root /usr/share/nginx/html; \
|
||||
index index.html; \
|
||||
location / { \
|
||||
try_files $uri $uri/ /index.html; \
|
||||
} \
|
||||
}' > /etc/nginx/conf.d/default.conf
|
||||
COPY package*.json ./
|
||||
RUN npm ci
|
||||
|
||||
EXPOSE 80
|
||||
COPY ../backup/backup .
|
||||
|
||||
CMD ["nginx", "-g", "daemon off;"]
|
||||
RUN npm run build
|
||||
|
||||
FROM node:20-alpine AS production
|
||||
|
||||
WORKDIR /app
|
||||
|
||||
RUN npm install -g serve
|
||||
|
||||
COPY --from=build /app/dist /app
|
||||
|
||||
EXPOSE 3000
|
||||
|
||||
CMD ["serve", "-s", ".", "-l", "3000"]
|
||||
|
||||
HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \
|
||||
CMD wget -qO- http://localhost:3000/ || exit 1
|
||||
47
README.md
Normal file
@ -0,0 +1,47 @@
|
||||
# Astro Starter Kit: Minimal
|
||||
|
||||
```sh
|
||||
npm create astro@latest -- --template minimal
|
||||
```
|
||||
|
||||
[](https://stackblitz.com/github/withastro/astro/tree/latest/examples/minimal)
|
||||
[](https://codesandbox.io/p/sandbox/github/withastro/astro/tree/latest/examples/minimal)
|
||||
[](https://codespaces.new/withastro/astro?devcontainer_path=.devcontainer/minimal/devcontainer.json)
|
||||
|
||||
> 🧑🚀 **Seasoned astronaut?** Delete this file. Have fun!
|
||||
|
||||
## 🚀 Project Structure
|
||||
|
||||
Inside of your Astro project, you'll see the following folders and files:
|
||||
|
||||
```text
|
||||
/
|
||||
├── public/
|
||||
├── src/
|
||||
│ └── pages/
|
||||
│ └── index.astro
|
||||
└── package.json
|
||||
```
|
||||
|
||||
Astro looks for `.astro` or `.md` files in the `src/pages/` directory. Each page is exposed as a route based on its file name.
|
||||
|
||||
There's nothing special about `src/components/`, but that's where we like to put any Astro/React/Vue/Svelte/Preact components.
|
||||
|
||||
Any static assets, like images, can be placed in the `public/` directory.
|
||||
|
||||
## 🧞 Commands
|
||||
|
||||
All commands are run from the root of the project, from a terminal:
|
||||
|
||||
| Command | Action |
|
||||
| :------------------------ | :----------------------------------------------- |
|
||||
| `npm install` | Installs dependencies |
|
||||
| `npm run dev` | Starts local dev server at `localhost:4321` |
|
||||
| `npm run build` | Build your production site to `./dist/` |
|
||||
| `npm run preview` | Preview your build locally, before deploying |
|
||||
| `npm run astro ...` | Run CLI commands like `astro add`, `astro check` |
|
||||
| `npm run astro -- --help` | Get help using the Astro CLI |
|
||||
|
||||
## 👀 Want to learn more?
|
||||
|
||||
Feel free to check [our documentation](https://docs.astro.build) or jump into our [Discord server](https://astro.build/chat).
|
||||
5
astro.config.mjs
Normal file
@ -0,0 +1,5 @@
|
||||
// @ts-check
|
||||
import { defineConfig } from 'astro/config';
|
||||
|
||||
// https://astro.build/config
|
||||
export default defineConfig({});
|
||||
48
fly.toml
@ -1,28 +1,42 @@
|
||||
app = 'gallus-pub'
|
||||
primary_region = 'fra'
|
||||
|
||||
[experimental]
|
||||
auto_rollback = true
|
||||
app = "gallus-pub"
|
||||
primary_region = "fra" # Frankfurt region, change if needed
|
||||
kill_signal = "SIGINT"
|
||||
kill_timeout = 5
|
||||
|
||||
[build]
|
||||
dockerfile = 'Dockerfile'
|
||||
dockerfile = "Dockerfile"
|
||||
|
||||
[env]
|
||||
PORT = "3000"
|
||||
NODE_ENV = "production"
|
||||
|
||||
[http_service]
|
||||
internal_port = 80
|
||||
internal_port = 3000
|
||||
force_https = true
|
||||
auto_stop_machines = 'stop'
|
||||
auto_stop_machines = true
|
||||
auto_start_machines = true
|
||||
min_machines_running = 0
|
||||
processes = ['app']
|
||||
processes = ["app"]
|
||||
|
||||
[http_service.concurrency]
|
||||
type = "connections"
|
||||
hard_limit = 1000
|
||||
soft_limit = 500
|
||||
|
||||
[[http_service.checks]]
|
||||
interval = '10s'
|
||||
timeout = '2s'
|
||||
grace_period = '5s'
|
||||
method = 'GET'
|
||||
path = '/'
|
||||
interval = "30s"
|
||||
timeout = "5s"
|
||||
grace_period = "10s"
|
||||
method = "GET"
|
||||
path = "/"
|
||||
protocol = "http"
|
||||
tls_skip_verify = false
|
||||
|
||||
[metrics]
|
||||
port = 9091
|
||||
path = "/metrics"
|
||||
|
||||
[[vm]]
|
||||
memory = '1gb'
|
||||
cpu_kind = 'shared'
|
||||
cpus = 1
|
||||
memory = "512MB"
|
||||
cpu_kind = "shared"
|
||||
cpus = 1
|
||||
4875
package-lock.json
generated
Normal file
14
package.json
Normal file
@ -0,0 +1,14 @@
|
||||
{
|
||||
"name": "",
|
||||
"type": "module",
|
||||
"version": "0.0.1",
|
||||
"scripts": {
|
||||
"dev": "astro dev",
|
||||
"build": "astro build",
|
||||
"preview": "astro preview",
|
||||
"astro": "astro"
|
||||
},
|
||||
"dependencies": {
|
||||
"astro": "^5.12.0"
|
||||
}
|
||||
}
|
||||
9
public/favicon.svg
Normal file
@ -0,0 +1,9 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 128 128">
|
||||
<path d="M50.4 78.5a75.1 75.1 0 0 0-28.5 6.9l24.2-65.7c.7-2 1.9-3.2 3.4-3.2h29c1.5 0 2.7 1.2 3.4 3.2l24.2 65.7s-11.6-7-28.5-7L67 45.5c-.4-1.7-1.6-2.8-2.9-2.8-1.3 0-2.5 1.1-2.9 2.7L50.4 78.5Zm-1.1 28.2Zm-4.2-20.2c-2 6.6-.6 15.8 4.2 20.2a17.5 17.5 0 0 1 .2-.7 5.5 5.5 0 0 1 5.7-4.5c2.8.1 4.3 1.5 4.7 4.7.2 1.1.2 2.3.2 3.5v.4c0 2.7.7 5.2 2.2 7.4a13 13 0 0 0 5.7 4.9v-.3l-.2-.3c-1.8-5.6-.5-9.5 4.4-12.8l1.5-1a73 73 0 0 0 3.2-2.2 16 16 0 0 0 6.8-11.4c.3-2 .1-4-.6-6l-.8.6-1.6 1a37 37 0 0 1-22.4 2.7c-5-.7-9.7-2-13.2-6.2Z" />
|
||||
<style>
|
||||
path { fill: #000; }
|
||||
@media (prefers-color-scheme: dark) {
|
||||
path { fill: #FFF; }
|
||||
}
|
||||
</style>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 749 B |
BIN
public/images/Background.png
Normal file
|
After Width: | Height: | Size: 506 KiB |
BIN
public/images/Logo.png
Normal file
|
After Width: | Height: | Size: 110 KiB |
BIN
public/images/Welcome.png
Normal file
|
After Width: | Height: | Size: 57 KiB |
BIN
public/images/crepes_sucette.jpg
Normal file
|
After Width: | Height: | Size: 124 KiB |
BIN
public/images/karaoke.jpg
Normal file
|
After Width: | Height: | Size: 94 KiB |
BIN
public/images/kevin_mcflannigan.jpeg
Normal file
|
After Width: | Height: | Size: 384 KiB |
BIN
public/images/pub_quiz.jpg
Normal file
|
After Width: | Height: | Size: 49 KiB |
BIN
public/pdf/Menu.pdf
Normal file
11
src/components/About.astro
Normal file
@ -0,0 +1,11 @@
|
||||
---
|
||||
import Layout from "../components/Layout.astro";
|
||||
---
|
||||
|
||||
<Layout>
|
||||
|
||||
<h1>About</h1>
|
||||
|
||||
<p>Hier findest du alle aktuellen und kommenden About im Gallus Pub.</p>
|
||||
|
||||
</Layout>
|
||||
42
src/components/Contact.astro
Normal file
@ -0,0 +1,42 @@
|
||||
---
|
||||
import Layout from "../components/Layout.astro";
|
||||
import "../../styles/components/ContactForm.css";
|
||||
---
|
||||
|
||||
<Layout>
|
||||
<div class="contact-container">
|
||||
<h1 class="contact-title">Kontakt</h1>
|
||||
|
||||
<form class="contact-form">
|
||||
<div class="form-group">
|
||||
<label for="name">Name</label>
|
||||
<input type="text" id="name" name="name" required>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label for="email">E-Mail</label>
|
||||
<input type="email" id="email" name="email" required>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label for="subject">Betreff</label>
|
||||
<input type="text" id="subject" name="subject" required>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label for="message">Nachricht</label>
|
||||
<textarea id="message" name="message" rows="5" required></textarea>
|
||||
</div>
|
||||
|
||||
<button type="submit" class="submit-button">Senden</button>
|
||||
</form>
|
||||
|
||||
<div class="whatsapp-container">
|
||||
<p>Oder kontaktiere uns direkt über WhatsApp:</p>
|
||||
<a href="https://wa.me/41772322770" class="whatsapp-link" target="_blank" rel="noopener noreferrer">
|
||||
<span class="whatsapp-icon">📱</span>
|
||||
<span>WhatsApp Chat starten</span>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</Layout>
|
||||
35
src/components/Drinks.astro
Normal file
@ -0,0 +1,35 @@
|
||||
---
|
||||
import "../../styles/components/Drinks.css"
|
||||
|
||||
const { id } = Astro.props;
|
||||
---
|
||||
<section id={id} class="Drinks">
|
||||
<h2 class="title">Drinks</h2>
|
||||
|
||||
<a href="/pdf/Menu.pdf" class="card-link" target="_blank" rel="noopener noreferrer">Getränkekarte</a>
|
||||
|
||||
<h3 class="monats-hit">Monats Hit</h3>
|
||||
|
||||
<div class="mate-vodka">
|
||||
<div class="circle" title="Mate Vodka">
|
||||
<span class="circle-label">Mate Vodka</span>
|
||||
</div>
|
||||
<div>Mate Vodka</div>
|
||||
</div>
|
||||
|
||||
<div class="circle-row">
|
||||
<div class="circle" title="Bier">
|
||||
<span class="circle-label">Bier</span>
|
||||
</div>
|
||||
<div class="circle" title="Wein">
|
||||
<span class="circle-label">Wein</span>
|
||||
</div>
|
||||
<div class="circle" title="Cocktails">
|
||||
<span class="circle-label">Cocktails</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<p class="note">
|
||||
Wir bieten eine Auswahl an erlesenen Getränken für jeden Geschmack. Besuche uns und entdecke unsere saisonalen Spezialitäten und Klassiker.
|
||||
</p>
|
||||
</section>
|
||||
31
src/components/EventsGrid.astro
Normal file
@ -0,0 +1,31 @@
|
||||
---
|
||||
// src/components/EventsGrid.astro
|
||||
|
||||
import HoverCard from "./HoverCard.astro";
|
||||
|
||||
interface Event {
|
||||
image: string;
|
||||
title: string;
|
||||
date: string;
|
||||
description: string;
|
||||
}
|
||||
const { events = [], id }: { events?: Event[]; id?: string } = Astro.props as {
|
||||
events?: Event[];
|
||||
id?: string;
|
||||
};
|
||||
import "../../styles/components/EventsGrid.css";
|
||||
---
|
||||
|
||||
<h2 class="section-title">Events</h2>
|
||||
<section id={id} class="events-gird container">
|
||||
{
|
||||
events.map((event: Event) => (
|
||||
<HoverCard
|
||||
title={event.title}
|
||||
date={event.date}
|
||||
description={event.description}
|
||||
image={event.image}
|
||||
/>
|
||||
))
|
||||
}
|
||||
</section>
|
||||
44
src/components/Footer.astro
Normal file
@ -0,0 +1,44 @@
|
||||
---
|
||||
// src/components/Footer.astro
|
||||
import "/styles/components/Footer.css"
|
||||
const currentYear = new Date().getFullYear();
|
||||
---
|
||||
|
||||
<footer class="footer">
|
||||
<div class="footer-content">
|
||||
<div class="copyright">
|
||||
© {currentYear} Gallus Pub. Alle Rechte vorbehalten.
|
||||
</div>
|
||||
|
||||
<div class="footer-sections">
|
||||
<div class="footer-section">
|
||||
<h3>Öffnungszeiten</h3>
|
||||
<p>Mittwoch: 19:00 - 00:00</p>
|
||||
<p>Donnerstag: 19:00 - 00:00</p>
|
||||
<p>Freitag: 19:00 - 01:00</p>
|
||||
<p>Samstag: 19:00 - 01:00</p>
|
||||
</div>
|
||||
|
||||
<div class="footer-section">
|
||||
<h3>Kontakt</h3>
|
||||
<p>Gallus Pub</p>
|
||||
<p>Metzgergasse 13</p>
|
||||
<p>9000 St. Gallen</p>
|
||||
<p>Reservierungen via Whatsapp</p>
|
||||
<p><a href="tel:0772322770">077 232 27 70</a></p>
|
||||
</div>
|
||||
|
||||
<div class="footer-section">
|
||||
<h3>Raumreservationen</h3>
|
||||
<p>Du planst einen Event?</p>
|
||||
<p>Der "St.Gallerruum" im 2.OG</p>
|
||||
<p>kann gemietet werden.</p>
|
||||
<br/>
|
||||
<p>Gerne öffnen wir auf Anfrage</p>
|
||||
<p>auch ausserhalb unserer</p>
|
||||
<p>Betriebszeiten.</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</footer>
|
||||
|
||||
28
src/components/Header.astro
Normal file
@ -0,0 +1,28 @@
|
||||
---
|
||||
// src/components/Header.astro
|
||||
const { url } = Astro;
|
||||
import "../../styles/components/Header.css";
|
||||
---
|
||||
|
||||
<header class="header">
|
||||
<div class="logo-container">
|
||||
<a href="/">
|
||||
<img src="/images/Logo.png" alt="Logo" class="logo" />
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<!-- Hauptnavigation: immer Home, About, Contact -->
|
||||
<nav class="nav-main">
|
||||
<div>
|
||||
<a href="/#hero">Home</a>
|
||||
<a href="/#events">Events</a>
|
||||
<a href="/#gallery">Galerie</a>
|
||||
<a href="/#drinks">Drinks</a>
|
||||
<a href="/#openings">Openings</a>
|
||||
<!--<a href="/#about">About</a>
|
||||
<a href="/#contact">Contact</a>-->
|
||||
</div>
|
||||
</nav>
|
||||
</header>
|
||||
|
||||
<div class="header-spacer"></div>
|
||||
27
src/components/Hero.astro
Normal file
@ -0,0 +1,27 @@
|
||||
---
|
||||
// src/components/Hero.astro
|
||||
import "../../styles/components/Hero.css"
|
||||
|
||||
const { id } = Astro.props;
|
||||
---
|
||||
|
||||
<section id={id} class="hero container">
|
||||
|
||||
<div class="hero-overlay">
|
||||
|
||||
<div class="hero-content">
|
||||
|
||||
<h1>Dein Irish Pub</h1>
|
||||
|
||||
<p>Im Herzen von St.Gallen</p>
|
||||
|
||||
<a href="#" class="button">Aktuelles ↓</a>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
</section>
|
||||
|
||||
<style>
|
||||
|
||||
</style>
|
||||
18
src/components/HoverCard.astro
Normal file
@ -0,0 +1,18 @@
|
||||
---
|
||||
// src/components/HoverCard.astro
|
||||
import "../../styles/components/HoverCard.css";
|
||||
const { title, description, image = "", date } = Astro.props;
|
||||
---
|
||||
|
||||
<article class="hover-card">
|
||||
<div class="image-container">
|
||||
<img class="card-image" src={image} alt={title} />
|
||||
</div>
|
||||
|
||||
<h3 class="card-title" set:html={title} />
|
||||
<h4 class="card_date">{date}</h4>
|
||||
|
||||
<div class="hover-text">
|
||||
<p set:html={description} />
|
||||
</div>
|
||||
</article>
|
||||
114
src/components/ImageCarousel.astro
Normal file
@ -0,0 +1,114 @@
|
||||
---
|
||||
// src/components/ImageCarousel.astro
|
||||
import "../../styles/components/ImageCarousel.css";
|
||||
|
||||
interface Image {
|
||||
src: string;
|
||||
alt: string;
|
||||
}
|
||||
|
||||
const { images = [], id } = Astro.props as { images: Image[], id?: string };
|
||||
---
|
||||
|
||||
<section id={id} class="image-carousel-container">
|
||||
<h2 class="section-title">Galerie</h2>
|
||||
<div class="image-carousel">
|
||||
<button class="nav-button prev-button" aria-label="Previous image">
|
||||
<span class="arrow">❮</span>
|
||||
</button>
|
||||
|
||||
<div class="carousel-images">
|
||||
<div class="carousel-track">
|
||||
{images.map((image, index) => (
|
||||
<div class="carousel-slide" data-index={index}>
|
||||
<img src={image.src} alt={image.alt} class="carousel-image" />
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<button class="nav-button next-button" aria-label="Next image">
|
||||
<span class="arrow">❯</span>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div class="carousel-indicators">
|
||||
{images.map((_, index) => (
|
||||
<button
|
||||
class="indicator-dot"
|
||||
data-index={index}
|
||||
aria-label={`Go to slide ${index + 1}`}
|
||||
></button>
|
||||
))}
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<script>
|
||||
// Initialize carousel functionality
|
||||
function initCarousel() {
|
||||
const carousel = document.querySelector('.image-carousel');
|
||||
const track = document.querySelector('.carousel-track');
|
||||
const slides = document.querySelectorAll('.carousel-slide');
|
||||
const prevButton = document.querySelector('.prev-button');
|
||||
const nextButton = document.querySelector('.next-button');
|
||||
const indicators = document.querySelectorAll('.indicator-dot');
|
||||
|
||||
if (!carousel || !track || !slides.length || !prevButton || !nextButton) return;
|
||||
|
||||
let currentIndex = 0;
|
||||
const slideCount = slides.length;
|
||||
|
||||
// Set initial active state
|
||||
updateCarousel();
|
||||
|
||||
// Add event listeners
|
||||
prevButton.addEventListener('click', () => {
|
||||
currentIndex = (currentIndex - 1 + slideCount) % slideCount;
|
||||
updateCarousel();
|
||||
});
|
||||
|
||||
nextButton.addEventListener('click', () => {
|
||||
currentIndex = (currentIndex + 1) % slideCount;
|
||||
updateCarousel();
|
||||
});
|
||||
|
||||
// Add click events to indicators
|
||||
indicators.forEach((dot, index) => {
|
||||
dot.addEventListener('click', () => {
|
||||
currentIndex = index;
|
||||
updateCarousel();
|
||||
});
|
||||
});
|
||||
|
||||
// Function to update carousel display
|
||||
function updateCarousel() {
|
||||
// Update active class on slides
|
||||
slides.forEach((slide, index) => {
|
||||
const position = index - currentIndex;
|
||||
|
||||
// Remove all position classes
|
||||
slide.classList.remove('prev', 'current', 'next');
|
||||
|
||||
// Add appropriate position class
|
||||
if (position === -1 || (position === slideCount - 1 && currentIndex === 0)) {
|
||||
slide.classList.add('prev');
|
||||
} else if (position === 0) {
|
||||
slide.classList.add('current');
|
||||
} else if (position === 1 || (position === -(slideCount - 1) && currentIndex === slideCount - 1)) {
|
||||
slide.classList.add('next');
|
||||
}
|
||||
});
|
||||
|
||||
// Update indicators
|
||||
indicators.forEach((dot, index) => {
|
||||
dot.classList.toggle('active', index === currentIndex);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// Run initialization when DOM is loaded
|
||||
document.addEventListener('DOMContentLoaded', initCarousel);
|
||||
|
||||
// Re-initialize on astro:page-load for Astro View Transitions
|
||||
document.addEventListener('astro:page-load', initCarousel);
|
||||
</script>
|
||||
35
src/components/Layout.astro
Normal file
@ -0,0 +1,35 @@
|
||||
---
|
||||
// src/components/Layout.astro
|
||||
import Header from "./Header.astro";
|
||||
import Footer from "./Footer.astro";
|
||||
import "../../styles/components/Layout.css"
|
||||
---
|
||||
|
||||
<!doctype html>
|
||||
|
||||
<html lang="de">
|
||||
|
||||
<head>
|
||||
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>Gallus Pub</title>
|
||||
<link rel="stylesheet" href="/styles/variables.css" />
|
||||
<link rel="stylesheet" href="/styles/index.css" />
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
||||
<Header />
|
||||
|
||||
<main class="container">
|
||||
|
||||
<slot />
|
||||
|
||||
</main>
|
||||
|
||||
<Footer />
|
||||
|
||||
</body>
|
||||
|
||||
</html>
|
||||
57
src/components/Welcome.astro
Normal file
@ -0,0 +1,57 @@
|
||||
---
|
||||
// src/components/Welcome.astro
|
||||
import "../../styles/components/Welcome.css"
|
||||
|
||||
const { id } = Astro.props;
|
||||
---
|
||||
|
||||
<section id={id} class="welcome container">
|
||||
|
||||
<div class="welcome-text">
|
||||
|
||||
<h2>Herzlich willkommen im Gallus Pub!</h2>
|
||||
|
||||
<p>
|
||||
Wie die meisten bereits wissen, ist hier jeder willkommen - ob jung
|
||||
oder alt, Rocker, Elf, Nerd, Meerjungfrau oder einfach nur du
|
||||
selbst. Unsere Türen stehen offen für alle, die Spass haben wollen
|
||||
und gute Gesellschaft suchen!
|
||||
</p>
|
||||
|
||||
<p><b>Unsere Highlights:</b></p>
|
||||
|
||||
<ul>
|
||||
<li>
|
||||
<b>Karaoke:</b> Von Mittwoch bis Samstag kannst du deine
|
||||
Stimme auf zwei Stockwerken zum Besten geben. Keine Sorge, es geht
|
||||
nicht darum, perfekt zu sein, sondern einfach Spass zu haben! Du singst
|
||||
gerne, aber lieber für dich? Dann kannst du den 2. OG auch privat
|
||||
mieten.
|
||||
</li>
|
||||
|
||||
<li>
|
||||
<b>Pub Quiz:</b> Jeden Freitag ab 20:00 Uhr testet ihr
|
||||
euer Wissen in verschiedenen Runden. Jede Woche gibt es ein neues
|
||||
Thema und einen neuen Champion.
|
||||
</li>
|
||||
|
||||
<li>
|
||||
<b>Getränke:</b> Geniesst frisches Guinness, Smithwicks,
|
||||
Gallus Old Style Ale und unsere leckeren Cocktails. Für Whisky-Liebhaber
|
||||
haben wir erlesene Sorten aus Schottland und Irland im Angebot.
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<p>
|
||||
Wir freuen uns darauf, euch bald bei uns begrüssen zu können! Lasst
|
||||
uns gemeinsam unvergessliche Abende feiern. - Sabrina & Raphael
|
||||
</p>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
<div class="welcome-image">
|
||||
<img src="/images/Welcome.png" alt="Welcome backgrount image" />
|
||||
</div>
|
||||
|
||||
</section>
|
||||
@ -1,47 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="de">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Coming Soon - Gallus Pub</title>
|
||||
<link rel="stylesheet" href="styles.css">
|
||||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0-beta3/css/all.min.css">
|
||||
</head>
|
||||
<body>
|
||||
<div class="container">
|
||||
<div class="logo-container">
|
||||
<img src="public/Logo.png" alt="Gallus Pub Logo">
|
||||
</div>
|
||||
|
||||
<h1 class="coming-soon">Coming Soon</h1>
|
||||
|
||||
<div class="social-links">
|
||||
<a href="https://www.instagram.com/galluspubsanktgallen/" target="_blank" class="social-link">
|
||||
<i class="fab fa-instagram"></i> Instagram
|
||||
</a>
|
||||
<a href="mailto:info@gallus-pub.ch" class="social-link">
|
||||
<i class="far fa-envelope"></i> Email
|
||||
</a>
|
||||
<a href="https://wa.me/+41772322770" target="_blank" class="social-link">
|
||||
<i class="fab fa-whatsapp"></i> WhatsApp Business
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<div class="opening-hours">
|
||||
<h2>Öffnungszeiten</h2>
|
||||
<p>Mittwoch: 19:00 - 24:00</p>
|
||||
<p>Donnerstag: 19:00 - 24:00</p>
|
||||
<p>Freitag: 19:00 - 01:00</p>
|
||||
<p>Samstag: 19:00 - 01:00</p>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="events-note">
|
||||
<p>Aktuelle Events findest du</p>
|
||||
<p>auf unserem Social Media.</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script src="script.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
11
src/pages/Gallery.astro
Normal file
@ -0,0 +1,11 @@
|
||||
---
|
||||
import Layout from "../components/Layout.astro";
|
||||
---
|
||||
|
||||
<Layout>
|
||||
|
||||
<h1>Gallery</h1>
|
||||
|
||||
<p>Hier findest du alle aktuellen und kommenden Gallery im Gallus Pub.</p>
|
||||
|
||||
</Layout>
|
||||
11
src/pages/Openings.astro
Normal file
@ -0,0 +1,11 @@
|
||||
---
|
||||
import Layout from "../components/Layout.astro";
|
||||
---
|
||||
|
||||
<Layout>
|
||||
|
||||
<h1>Openings</h1>
|
||||
|
||||
<p>Hier findest du alle aktuellen und kommenden Openings im Gallus Pub.</p>
|
||||
|
||||
</Layout>
|
||||
76
src/pages/index.astro
Normal file
@ -0,0 +1,76 @@
|
||||
---
|
||||
// src/pages/index.astro
|
||||
import Layout from "../components/Layout.astro";
|
||||
import Hero from "../components/Hero.astro";
|
||||
import Welcome from "../components/Welcome.astro";
|
||||
import EventsGrid from "../components/EventsGrid.astro";
|
||||
import Drinks from "../components/Drinks.astro";
|
||||
import ImageCarousel from "../components/ImageCarousel.astro";
|
||||
import Contact from "../components/Contact.astro";
|
||||
import About from "../components/About.astro";
|
||||
|
||||
const events = [
|
||||
{
|
||||
image: "/images/karaoke.jpg",
|
||||
title: "Karaoke",
|
||||
date: "Mittwoch - Samstag",
|
||||
description: `
|
||||
Bei uns gibt es Karaoke Mi-Sa!! <br>
|
||||
Seid ihr eine Gruppe und lieber unter euch? ..unseren 2.Stock kannst du auch mieten ;) <br>
|
||||
Reserviere am besten gleich per Whatsapp <a href="tel:+41772322770">077 232 27 70</a>
|
||||
`,
|
||||
},
|
||||
{
|
||||
image: "/images/pub_quiz.jpg",
|
||||
title: "Pub Quiz",
|
||||
date: "Jeden Freitag",
|
||||
description: `
|
||||
Jeden Freitag findet unser <b>Pub Quiz</b> statt. Gespielt wird tischweise in 3-4 Runden. <br>
|
||||
Jede Woche gibt es ein anderes Thema. Es geht um Ruhm und Ehre und zusätzlich werden die Sieger der Herzen durch das Publikum gekürt! <3 <br>
|
||||
Auch Einzelpersonen sind herzlich willkommen! <br>
|
||||
*zum mitmachen minimum 1 Getränk konsumieren oder 5CHF
|
||||
`,
|
||||
},
|
||||
{
|
||||
image: "/images/crepes_sucette.jpg",
|
||||
title: "Crepes Sucette <br /> Live Music im Gallus Pub!",
|
||||
date: "Do, 04. September 2025",
|
||||
description: `
|
||||
<b>20:00 Uhr</b> <br>
|
||||
<a href="Metzgergasse 13, 9000 St. Gallen">Metzgergasse 13, 9000 St. Gallen</a> <br>
|
||||
Erlebt einen musikalischen Abend mit der Band <b>Crepes Sucette</b> <br>
|
||||
Jetzt reservieren: <a href="tel:+41772322770">077 232 27 70</a>`,
|
||||
},
|
||||
{
|
||||
image: "/images/kevin_mcflannigan.jpeg",
|
||||
title: "Kevin McFlannigan <br> Live Music im Gallus Pub!",
|
||||
date: "Sa, 27. September 2025",
|
||||
description: `
|
||||
<b>ab 20:00 Uhr</b> <br>
|
||||
Singer & Songwriter Kevin McFlannigan <br>
|
||||
Eintritt ist Frei / Hutkollekte <br>
|
||||
`,
|
||||
},
|
||||
];
|
||||
|
||||
const images = [
|
||||
{ src: "/images/Logo.png", alt: "Erstes Bild" },
|
||||
{ src: "/images/Logo.png", alt: "Zweites Bild" },
|
||||
{ src: "/images/Logo.png", alt: "Drittes Bild" },
|
||||
{ src: "/images/Logo.png", alt: "Viertes Bild" },
|
||||
{ src: "/images/Logo.png", alt: "Fünftes Bild" },
|
||||
{ src: "/images/Logo.png", alt: "Sechstes Bild" },
|
||||
{ src: "/images/Logo.png", alt: "Siebtes Bild" },
|
||||
{ src: "/images/Logo.png", alt: "Achtes Bild" },
|
||||
{ src: "/images/Logo.png", alt: "Neuntes Bild" },
|
||||
{ src: "/images/Logo.png", alt: "Zehntes Bild" },
|
||||
];
|
||||
---
|
||||
|
||||
<Layout>
|
||||
<Hero id="hero" />
|
||||
<Welcome id="welcome" />
|
||||
<EventsGrid id="events" events={events} />
|
||||
<ImageCarousel id="gallery" images={images} />
|
||||
<Drinks id="drinks" />
|
||||
</Layout>
|
||||
@ -1,37 +0,0 @@
|
||||
// Wait for the DOM to be fully loaded
|
||||
document.addEventListener('DOMContentLoaded', function() {
|
||||
// Add a fade-in effect to the main elements
|
||||
const elements = [
|
||||
document.querySelector('.logo'),
|
||||
document.querySelector('.coming-soon'),
|
||||
document.querySelector('.social-links'),
|
||||
document.querySelector('.opening-hours'),
|
||||
document.querySelector('.events-note')
|
||||
];
|
||||
|
||||
// Apply fade-in animation with delay for each element
|
||||
elements.forEach((element, index) => {
|
||||
if (element) {
|
||||
element.style.opacity = '0';
|
||||
element.style.transition = 'opacity 1s ease-in-out';
|
||||
|
||||
// Stagger the animations
|
||||
setTimeout(() => {
|
||||
element.style.opacity = '1';
|
||||
}, 300 * index);
|
||||
}
|
||||
});
|
||||
|
||||
// Add a subtle hover effect to the logo
|
||||
const logo = document.querySelector('.logo');
|
||||
if (logo) {
|
||||
logo.addEventListener('mouseover', function() {
|
||||
this.style.transform = 'scale(1.05)';
|
||||
this.style.transition = 'transform 0.3s ease';
|
||||
});
|
||||
|
||||
logo.addEventListener('mouseout', function() {
|
||||
this.style.transform = 'scale(1)';
|
||||
});
|
||||
}
|
||||
});
|
||||
149
src/styles.css
@ -1,149 +0,0 @@
|
||||
/* Global styles */
|
||||
* {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
body {
|
||||
font-family: 'Arial', sans-serif;
|
||||
background-color: #213b28;
|
||||
color: #ceb39b;
|
||||
line-height: 1.6;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
min-height: 100vh;
|
||||
}
|
||||
|
||||
.container {
|
||||
max-width: 800px;
|
||||
margin: 0 auto;
|
||||
padding: 40px 20px;
|
||||
text-align: center;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
min-height: 100vh;
|
||||
}
|
||||
|
||||
/* Logo styles */
|
||||
.logo-container {
|
||||
margin-bottom: 30px;
|
||||
width: 100%;
|
||||
max-width: 100%;
|
||||
}
|
||||
|
||||
.logo-container img {
|
||||
max-width: 100%;
|
||||
height: auto;
|
||||
display: block;
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
.logo {
|
||||
font-size: 48px;
|
||||
font-weight: bold;
|
||||
color: #333;
|
||||
padding: 20px;
|
||||
border: 3px solid #333;
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.logo img {
|
||||
max-width: 200px;
|
||||
height: auto;
|
||||
display: block;
|
||||
}
|
||||
|
||||
/* Coming soon text */
|
||||
.coming-soon {
|
||||
font-size: 36px;
|
||||
margin-bottom: 40px;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 4px;
|
||||
}
|
||||
|
||||
/* Social links */
|
||||
.social-links {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
flex-wrap: wrap;
|
||||
gap: 20px;
|
||||
margin-bottom: 40px;
|
||||
}
|
||||
|
||||
.social-link {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
padding: 10px 20px;
|
||||
background-color: #333;
|
||||
color: white;
|
||||
text-decoration: none;
|
||||
border-radius: 30px;
|
||||
transition: all 0.3s ease;
|
||||
}
|
||||
|
||||
.social-link i {
|
||||
margin-right: 10px;
|
||||
font-size: 18px;
|
||||
}
|
||||
|
||||
.social-link:hover {
|
||||
background-color: #555;
|
||||
transform: translateY(-3px);
|
||||
}
|
||||
|
||||
/* Opening hours */
|
||||
.opening-hours {
|
||||
margin-bottom: 30px;
|
||||
padding: 20px;
|
||||
border-top: 1px solid #ddd;
|
||||
border-bottom: 1px solid #ddd;
|
||||
width: 100%;
|
||||
max-width: 500px;
|
||||
}
|
||||
|
||||
.opening-hours h2 {
|
||||
margin-bottom: 15px;
|
||||
font-size: 24px;
|
||||
}
|
||||
|
||||
.opening-hours p {
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
|
||||
/* Events note */
|
||||
.events-note {
|
||||
font-style: italic;
|
||||
margin-top: 20px;
|
||||
padding: 10px;
|
||||
background-color: #2F2F2F;
|
||||
color: #fff;
|
||||
border-radius: 5px;
|
||||
}
|
||||
|
||||
/* Responsive adjustments */
|
||||
@media (max-width: 600px) {
|
||||
.social-links {
|
||||
flex-direction: column;
|
||||
gap: 10px;
|
||||
}
|
||||
|
||||
.logo {
|
||||
font-size: 36px;
|
||||
}
|
||||
|
||||
.coming-soon {
|
||||
font-size: 28px;
|
||||
}
|
||||
|
||||
.container {
|
||||
padding: 20px 10px;
|
||||
}
|
||||
|
||||
.logo-container img {
|
||||
max-width: 90%;
|
||||
}
|
||||
}
|
||||
127
styles/components/ContactForm.css
Normal file
@ -0,0 +1,127 @@
|
||||
/* styles/components/ContactForm.css */
|
||||
|
||||
.contact-container {
|
||||
max-width: 800px;
|
||||
margin: 2rem auto;
|
||||
padding: 0 1rem;
|
||||
}
|
||||
|
||||
.contact-title {
|
||||
margin-top: 70px;
|
||||
padding-top: 2rem;
|
||||
text-align: center;
|
||||
margin-bottom: 2rem;
|
||||
font-size: 2.5rem;
|
||||
color: var(--color-text);
|
||||
}
|
||||
|
||||
.contact-form {
|
||||
background-color: rgba(33, 59, 40, 0.05);
|
||||
padding: 2rem;
|
||||
border-radius: 8px;
|
||||
margin-bottom: 2rem;
|
||||
}
|
||||
|
||||
.form-group {
|
||||
margin-bottom: 1.5rem;
|
||||
}
|
||||
|
||||
.form-group label {
|
||||
display: block;
|
||||
margin-bottom: 0.5rem;
|
||||
font-weight: bold;
|
||||
color: var(--color-text);
|
||||
}
|
||||
|
||||
.form-group input,
|
||||
.form-group textarea {
|
||||
width: 100%;
|
||||
padding: 0.75rem;
|
||||
border: 1px solid #ccc;
|
||||
border-radius: 4px;
|
||||
font-family: inherit;
|
||||
font-size: 1rem;
|
||||
background-color: #fff;
|
||||
}
|
||||
|
||||
.form-group textarea {
|
||||
resize: vertical;
|
||||
}
|
||||
|
||||
.form-group input:focus,
|
||||
.form-group textarea:focus {
|
||||
outline: none;
|
||||
border-color: #213b28;
|
||||
box-shadow: 0 0 0 2px rgba(33, 59, 40, 0.2);
|
||||
}
|
||||
|
||||
.submit-button {
|
||||
background-color: #213b28;
|
||||
color: white;
|
||||
border: none;
|
||||
padding: 0.75rem 1.5rem;
|
||||
font-size: 1rem;
|
||||
font-weight: bold;
|
||||
border-radius: 4px;
|
||||
cursor: pointer;
|
||||
transition: background-color 0.3s ease;
|
||||
}
|
||||
|
||||
.submit-button:hover {
|
||||
background-color: #2a4c35;
|
||||
}
|
||||
|
||||
.whatsapp-container {
|
||||
text-align: center;
|
||||
margin: 2rem 0;
|
||||
}
|
||||
|
||||
.whatsapp-link {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
background-color: #25D366;
|
||||
color: white;
|
||||
text-decoration: none;
|
||||
padding: 0.75rem 1.5rem;
|
||||
border-radius: 4px;
|
||||
font-weight: bold;
|
||||
transition: background-color 0.3s ease;
|
||||
margin-top: 0.5rem;
|
||||
}
|
||||
|
||||
.whatsapp-link:hover {
|
||||
background-color: #128C7E;
|
||||
}
|
||||
|
||||
.whatsapp-icon {
|
||||
font-size: 1.2rem;
|
||||
margin-right: 0.5rem;
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
/* Responsive adjustments */
|
||||
@media (max-width: 768px) {
|
||||
.contact-form {
|
||||
padding: 1.5rem;
|
||||
}
|
||||
|
||||
.contact-title {
|
||||
font-size: 2rem;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 480px) {
|
||||
.contact-form {
|
||||
padding: 1rem;
|
||||
}
|
||||
|
||||
.contact-title {
|
||||
font-size: 1.75rem;
|
||||
}
|
||||
|
||||
.submit-button,
|
||||
.whatsapp-link {
|
||||
width: 100%;
|
||||
justify-content: center;
|
||||
}
|
||||
}
|
||||
195
styles/components/Drinks.css
Normal file
@ -0,0 +1,195 @@
|
||||
.Drinks {
|
||||
font-family: var(--font-family-primary);
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
margin-top: 2rem;
|
||||
text-align: center;
|
||||
background-color: var(--color-accent-green);
|
||||
color: var(--color-accent-beige);
|
||||
padding: 2rem;
|
||||
width: 100%;
|
||||
border-radius: var(--border-radius);
|
||||
box-shadow: var(--box-shadow);
|
||||
}
|
||||
|
||||
.title {
|
||||
font-size: var(--font-size-large);
|
||||
margin-bottom: 1.5rem;
|
||||
font-weight: bold;
|
||||
color: var(--color-text);
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 1px;
|
||||
}
|
||||
|
||||
.card-link {
|
||||
border: 2px solid var(--color-accent-beige);
|
||||
padding: 0.75rem 1.5rem;
|
||||
margin-bottom: 2.5rem;
|
||||
color: var(--color-text);
|
||||
background-color: var(--color-background);
|
||||
text-decoration: none;
|
||||
border-radius: var(--border-radius);
|
||||
font-weight: bold;
|
||||
transition: all var(--transition-standard);
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.card-link:hover {
|
||||
background-color: var(--color-accent-beige);
|
||||
color: var(--color-accent-green);
|
||||
transform: translateY(-3px);
|
||||
box-shadow: var(--box-shadow);
|
||||
}
|
||||
|
||||
.monats-hit {
|
||||
margin-bottom: 1.5rem;
|
||||
font-size: var(--font-size-medium);
|
||||
color: var(--color-text);
|
||||
font-weight: bold;
|
||||
position: relative;
|
||||
padding-bottom: 0.5rem;
|
||||
}
|
||||
|
||||
.monats-hit::after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
left: 50%;
|
||||
transform: translateX(-50%);
|
||||
width: 50px;
|
||||
height: 2px;
|
||||
background-color: var(--color-accent-beige);
|
||||
}
|
||||
|
||||
.mate-vodka {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
margin-bottom: 1.5rem;
|
||||
padding: 1rem;
|
||||
background-color: rgba(0, 0, 0, 0.2);
|
||||
border-radius: var(--border-radius);
|
||||
width: 80%;
|
||||
max-width: 300px;
|
||||
}
|
||||
|
||||
.mate-vodka div:not(.circle) {
|
||||
margin-top: 0.5rem;
|
||||
font-weight: bold;
|
||||
color: var(--color-accent-beige);
|
||||
}
|
||||
|
||||
.circle {
|
||||
height: 6em;
|
||||
width: 6em;
|
||||
border: 2px solid var(--color-accent-beige);
|
||||
border-radius: 50%;
|
||||
margin: 0.5rem;
|
||||
background: radial-gradient(circle at 30% 30%, rgba(206, 179, 155, 0.2), transparent 70%);
|
||||
box-shadow: 0 0 10px rgba(0, 0, 0, 0.3);
|
||||
transition: all var(--transition-standard);
|
||||
position: relative;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.circle:hover {
|
||||
transform: scale(1.05);
|
||||
border-color: var(--color-text);
|
||||
}
|
||||
|
||||
.circle-label {
|
||||
opacity: 0;
|
||||
color: var(--color-text);
|
||||
font-weight: bold;
|
||||
font-size: 0.8rem;
|
||||
text-align: center;
|
||||
transition: opacity var(--transition-standard);
|
||||
position: absolute;
|
||||
}
|
||||
|
||||
.circle:hover .circle-label {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
.circle-row {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
flex-wrap: wrap;
|
||||
gap: 1.5rem;
|
||||
margin: 1.5rem 0;
|
||||
}
|
||||
|
||||
.note {
|
||||
margin-top: 2rem;
|
||||
font-style: italic;
|
||||
text-align: center;
|
||||
color: var(--color-text);
|
||||
max-width: 80%;
|
||||
line-height: 1.6;
|
||||
padding: 1rem;
|
||||
border-top: 1px solid rgba(206, 179, 155, 0.3);
|
||||
border-bottom: 1px solid rgba(206, 179, 155, 0.3);
|
||||
}
|
||||
|
||||
/* Responsive Design */
|
||||
@media (max-width: 768px) {
|
||||
.Drinks {
|
||||
padding: 1.5rem;
|
||||
}
|
||||
|
||||
.title {
|
||||
font-size: calc(var(--font-size-medium) + 0.2rem);
|
||||
}
|
||||
|
||||
.mate-vodka {
|
||||
width: 90%;
|
||||
}
|
||||
|
||||
.circle {
|
||||
height: 5em;
|
||||
width: 5em;
|
||||
}
|
||||
|
||||
.circle-label {
|
||||
font-size: 0.7rem;
|
||||
}
|
||||
|
||||
/* Make labels always visible on touch devices */
|
||||
.circle-label {
|
||||
opacity: 1;
|
||||
background-color: rgba(0, 0, 0, 0.5);
|
||||
padding: 2px 5px;
|
||||
border-radius: 3px;
|
||||
}
|
||||
|
||||
.circle-row {
|
||||
gap: 1rem;
|
||||
}
|
||||
|
||||
.note {
|
||||
max-width: 95%;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 480px) {
|
||||
.circle-row {
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.card-link {
|
||||
padding: 0.5rem 1rem;
|
||||
}
|
||||
|
||||
.circle {
|
||||
margin: 1rem 0;
|
||||
}
|
||||
|
||||
.mate-vodka {
|
||||
padding: 0.8rem;
|
||||
}
|
||||
}
|
||||
28
styles/components/EventsGrid.css
Normal file
@ -0,0 +1,28 @@
|
||||
.section-title {
|
||||
text-align: center;
|
||||
margin-bottom: 1.5rem;
|
||||
font-size: 2rem;
|
||||
font-weight: bold;
|
||||
color: var(--color-text);
|
||||
}
|
||||
|
||||
.events-gird {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
justify-content: center;
|
||||
gap: var(--gap-standard);
|
||||
padding: var(--padding-vertical) var(--padding-horizontal);
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
@media (min-width: 1600px) {
|
||||
.events-gird {
|
||||
justify-content: space-between;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 1599px) {
|
||||
.events-gird {
|
||||
justify-content: space-around;
|
||||
}
|
||||
}
|
||||
62
styles/components/Footer.css
Normal file
@ -0,0 +1,62 @@
|
||||
.footer {
|
||||
background-color: #213b28;
|
||||
color: white;
|
||||
padding: 3rem 0;
|
||||
margin-top: 4rem;
|
||||
}
|
||||
|
||||
.footer-content {
|
||||
max-width: 1200px;
|
||||
margin: 0 auto;
|
||||
padding: 0 1rem;
|
||||
}
|
||||
|
||||
.copyright {
|
||||
text-align: center;
|
||||
margin-bottom: 2rem;
|
||||
padding-bottom: 1rem;
|
||||
border-bottom: 1px solid rgba(255, 255, 255, 0.1);
|
||||
}
|
||||
|
||||
.footer-sections {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
|
||||
gap: 2rem;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.footer-section {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.footer-section h3 {
|
||||
color: #ffffff;
|
||||
margin-bottom: 1rem;
|
||||
font-size: 1.2rem;
|
||||
}
|
||||
|
||||
.footer-section p {
|
||||
margin: 0.5rem 0;
|
||||
color: #cccccc;
|
||||
font-size: 0.9rem;
|
||||
}
|
||||
|
||||
.footer-section a {
|
||||
color: #ffffff;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.footer-section a:hover {
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
@media (max-width: 768px) {
|
||||
.footer-sections {
|
||||
grid-template-columns: 1fr;
|
||||
gap: 2rem;
|
||||
}
|
||||
|
||||
.footer-section {
|
||||
padding: 0 1rem;
|
||||
}
|
||||
}
|
||||
92
styles/components/Header.css
Normal file
@ -0,0 +1,92 @@
|
||||
.header {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
background-color: #0e0c0c;
|
||||
z-index: 1000;
|
||||
box-shadow: 0 2px 5px rgba(0, 0, 0, 0.1);
|
||||
backdrop-filter: blur(5px);
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
padding: 1rem 2rem;
|
||||
height: 70px;
|
||||
width: 100%;
|
||||
border-bottom: 1px solid #444;
|
||||
}
|
||||
|
||||
.header-spacer {
|
||||
height: 70px;
|
||||
/* Should match the header height */
|
||||
}
|
||||
|
||||
|
||||
.logo-container {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.logo {
|
||||
margin-left: 2em;
|
||||
height: 4em;
|
||||
width: auto;
|
||||
transition: transform 0.3s ease;
|
||||
}
|
||||
|
||||
.logo:hover {
|
||||
transform: scale(1.05);
|
||||
}
|
||||
|
||||
.nav-main {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.nav-main a {
|
||||
margin: 0 1rem;
|
||||
color: white;
|
||||
text-decoration: none;
|
||||
font-size: 1rem;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.nav-main a:hover {
|
||||
color: #ffa500;
|
||||
}
|
||||
|
||||
@media (max-width: 768px) {
|
||||
.header {
|
||||
height: 65px;
|
||||
}
|
||||
|
||||
.logo {
|
||||
margin-left: 1em;
|
||||
height: 3em;
|
||||
}
|
||||
|
||||
.header-spacer {
|
||||
height: 65px;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 480px) {
|
||||
.header {
|
||||
padding: 0.5rem;
|
||||
height: 60px;
|
||||
}
|
||||
|
||||
.logo {
|
||||
margin-left: 0.5em;
|
||||
height: 2.5em;
|
||||
}
|
||||
|
||||
.nav-main a {
|
||||
margin: 0 0.5rem;
|
||||
font-size: 0.9rem;
|
||||
}
|
||||
|
||||
.header-spacer {
|
||||
height: 60px;
|
||||
}
|
||||
}
|
||||
66
styles/components/Hero.css
Normal file
@ -0,0 +1,66 @@
|
||||
/* === Hero === */
|
||||
.hero-overlay {
|
||||
background-image: linear-gradient(to bottom, rgba(0, 0, 0, 0.3), rgba(0, 0, 0, 1)), url('/images/Background.png');
|
||||
background-size: cover;
|
||||
background-position: center;
|
||||
background-repeat: no-repeat;
|
||||
margin-top: 2em;
|
||||
}
|
||||
|
||||
h1 {
|
||||
padding-top: 2em;
|
||||
}
|
||||
|
||||
.hero {
|
||||
position: relative;
|
||||
height: 70vh;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
color: white;
|
||||
margin-bottom: 2rem;
|
||||
}
|
||||
|
||||
.hero-overlay {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
/* Background is set in the component */
|
||||
}
|
||||
|
||||
.hero-content {
|
||||
position: relative;
|
||||
text-align: center;
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
.hero-content h1 {
|
||||
font-size: 4rem;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.hero-content p {
|
||||
margin: 0.5rem 0 1rem 0;
|
||||
font-size: 1.2rem;
|
||||
}
|
||||
|
||||
.button {
|
||||
margin-top: 2rem;
|
||||
padding: 0.8rem 2rem;
|
||||
background: linear-gradient(45deg, #ffa500, #ff7f00);
|
||||
color: white;
|
||||
border: none;
|
||||
border-radius: 30px;
|
||||
font-size: 1rem;
|
||||
font-weight: bold;
|
||||
text-decoration: none;
|
||||
box-shadow: 0 4px 15px rgba(0, 0, 0, 0.3);
|
||||
transition: transform 0.2s, box-shadow 0.2s;
|
||||
}
|
||||
|
||||
.button:hover {
|
||||
transform: translateY(-3px);
|
||||
box-shadow: 0 6px 20px rgba(0, 0, 0, 0.4);
|
||||
}
|
||||
114
styles/components/HoverCard.css
Normal file
@ -0,0 +1,114 @@
|
||||
.hover-card {
|
||||
position: relative;
|
||||
width: 350px;
|
||||
height: 400px;
|
||||
border-radius: var(--border-radius);
|
||||
background-color: var(--color-accent-green);
|
||||
box-shadow: var(--box-shadow);
|
||||
transition: transform var(--transition-standard);
|
||||
overflow: hidden;
|
||||
margin: var(--margin-standard);
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.hover-card:hover {
|
||||
transform: translateY(-5px);
|
||||
}
|
||||
|
||||
.card-title {
|
||||
padding: 15px 15px 5px 15px;
|
||||
margin: 0;
|
||||
color: var(--color-accent-beige);
|
||||
font-size: var(--font-size-medium);
|
||||
text-align: center;
|
||||
order: -2;
|
||||
}
|
||||
|
||||
.card_date {
|
||||
padding: 0 15px 15px 15px;
|
||||
margin: 0;
|
||||
color: var(--color-accent-beige);
|
||||
font-size: var(--font-size-small);
|
||||
text-align: center;
|
||||
font-style: italic;
|
||||
order: -1;
|
||||
}
|
||||
|
||||
.image-container {
|
||||
flex-grow: 1;
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.card-image {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
object-fit: cover;
|
||||
transition: opacity 0.3s ease;
|
||||
}
|
||||
|
||||
.hover-text {
|
||||
font-size: var(--font-size-small-medium);
|
||||
text-align: center;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background-color: var(--color-accent-green-transparent);
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
padding: 20px;
|
||||
opacity: 0;
|
||||
transition: opacity var(--transition-standard);
|
||||
}
|
||||
|
||||
.hover-text div {
|
||||
color: var(--color-accent-beige);
|
||||
text-align: center;
|
||||
max-height: 100%;
|
||||
width: 100%;
|
||||
overflow-y: auto;
|
||||
padding-right: 5px;
|
||||
}
|
||||
|
||||
.hover-text div::-webkit-scrollbar {
|
||||
width: 5px;
|
||||
}
|
||||
|
||||
.hover-text div::-webkit-scrollbar-track {
|
||||
background: rgba(0, 0, 0, 0.1);
|
||||
border-radius: 10px;
|
||||
}
|
||||
|
||||
.hover-text div::-webkit-scrollbar-thumb {
|
||||
background: var(--color-accent-beige);
|
||||
border-radius: 10px;
|
||||
}
|
||||
|
||||
.hover-text div {
|
||||
scrollbar-width: thin;
|
||||
scrollbar-color: var(--color-accent-beige) rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
|
||||
.hover-card:hover .hover-text {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
.hover-card:hover .card-image {
|
||||
opacity: 0.1;
|
||||
}
|
||||
|
||||
.hover-text p {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
@media (max-width: 768px) {
|
||||
.hover-card {
|
||||
width: 100%;
|
||||
max-width: 350px;
|
||||
}
|
||||
}
|
||||
176
styles/components/ImageCarousel.css
Normal file
@ -0,0 +1,176 @@
|
||||
/* styles/components/ImageCarousel.css */
|
||||
|
||||
.image-carousel-container {
|
||||
width: 100%;
|
||||
max-width: 1200px;
|
||||
margin: 2rem auto;
|
||||
padding: 0 1rem;
|
||||
}
|
||||
|
||||
.section-title {
|
||||
text-align: center;
|
||||
margin-bottom: 1.5rem;
|
||||
font-size: 2rem;
|
||||
font-weight: bold;
|
||||
color: var(--color-text);
|
||||
}
|
||||
|
||||
.image-carousel {
|
||||
position: relative;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
overflow: hidden;
|
||||
height: 400px;
|
||||
}
|
||||
|
||||
.carousel-images {
|
||||
position: relative;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.carousel-track {
|
||||
display: flex;
|
||||
height: 100%;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.carousel-slide {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
opacity: 0;
|
||||
transition: all 0.5s ease;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
transform: scale(0.8);
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
/* Current slide - center and fully visible */
|
||||
.carousel-slide.current {
|
||||
opacity: 1;
|
||||
transform: scale(1);
|
||||
z-index: 3;
|
||||
}
|
||||
|
||||
/* Previous slide - left side, partially visible */
|
||||
.carousel-slide.prev {
|
||||
opacity: 0.7;
|
||||
transform: translateX(-30%) scale(0.85);
|
||||
z-index: 2;
|
||||
}
|
||||
|
||||
/* Next slide - right side, partially visible */
|
||||
.carousel-slide.next {
|
||||
opacity: 0.7;
|
||||
transform: translateX(30%) scale(0.85);
|
||||
z-index: 2;
|
||||
}
|
||||
|
||||
.carousel-image {
|
||||
max-width: 100%;
|
||||
max-height: 100%;
|
||||
object-fit: contain;
|
||||
border-radius: 8px;
|
||||
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
|
||||
/* Navigation buttons */
|
||||
.nav-button {
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
transform: translateY(-50%);
|
||||
background-color: rgba(255, 255, 255, 0.7);
|
||||
border: none;
|
||||
border-radius: 50%;
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
cursor: pointer;
|
||||
z-index: 10;
|
||||
transition: background-color 0.3s ease;
|
||||
}
|
||||
|
||||
.nav-button:hover {
|
||||
background-color: rgba(255, 255, 255, 0.9);
|
||||
}
|
||||
|
||||
.prev-button {
|
||||
left: 10px;
|
||||
}
|
||||
|
||||
.next-button {
|
||||
right: 10px;
|
||||
}
|
||||
|
||||
.arrow {
|
||||
font-size: 18px;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
/* Indicators */
|
||||
.carousel-indicators {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
margin-top: 1rem;
|
||||
gap: 8px;
|
||||
}
|
||||
|
||||
.indicator-dot {
|
||||
width: 12px;
|
||||
height: 12px;
|
||||
border-radius: 50%;
|
||||
background-color: #ccc;
|
||||
border: none;
|
||||
cursor: pointer;
|
||||
transition: background-color 0.3s ease;
|
||||
}
|
||||
|
||||
.indicator-dot.active {
|
||||
background-color: #333;
|
||||
}
|
||||
|
||||
/* Responsive adjustments */
|
||||
@media (max-width: 768px) {
|
||||
.image-carousel {
|
||||
height: 300px;
|
||||
}
|
||||
|
||||
.carousel-slide.prev,
|
||||
.carousel-slide.next {
|
||||
opacity: 0.5;
|
||||
transform: scale(0.7);
|
||||
}
|
||||
|
||||
.carousel-slide.prev {
|
||||
transform: translateX(-20%) scale(0.7);
|
||||
}
|
||||
|
||||
.carousel-slide.next {
|
||||
transform: translateX(20%) scale(0.7);
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 480px) {
|
||||
.image-carousel {
|
||||
height: 250px;
|
||||
}
|
||||
|
||||
.carousel-slide.prev,
|
||||
.carousel-slide.next {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.nav-button {
|
||||
width: 30px;
|
||||
height: 30px;
|
||||
}
|
||||
}
|
||||
15
styles/components/Layout.css
Normal file
@ -0,0 +1,15 @@
|
||||
html, body {
|
||||
height: 100%;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
body {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
min-height: 100vh;
|
||||
}
|
||||
|
||||
main {
|
||||
flex: 1;
|
||||
padding: 0 1rem;
|
||||
}
|
||||
41
styles/components/Welcome.css
Normal file
@ -0,0 +1,41 @@
|
||||
/* === Welcome === */
|
||||
.welcome {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
align-items: center;
|
||||
background-color: #1f3a2d;
|
||||
padding: 3rem 0;
|
||||
margin-bottom: 2rem;
|
||||
gap: 2rem;
|
||||
}
|
||||
|
||||
.welcome-text {
|
||||
order: 1;
|
||||
flex: 2 1 400px;
|
||||
padding: 0 1.6rem 0 2rem;
|
||||
color: #fff3e0;
|
||||
}
|
||||
|
||||
.welcome-text h2 {
|
||||
font-size: 2.5rem;
|
||||
margin-bottom: 1rem;
|
||||
color: #e8c6a7;
|
||||
}
|
||||
|
||||
.welcome-text ul {
|
||||
margin: 1rem 0;
|
||||
padding-left: 1.2rem;
|
||||
}
|
||||
|
||||
.welcome-image {
|
||||
order: 2;
|
||||
height: 100%;
|
||||
flex: 1 1 300px;
|
||||
margin-right: 2em;
|
||||
}
|
||||
|
||||
.welcome-image img {
|
||||
width: 100%;
|
||||
height: auto;
|
||||
border-radius: 8px;
|
||||
}
|
||||
34
styles/index.css
Normal file
@ -0,0 +1,34 @@
|
||||
/* === Global Reset === */
|
||||
* {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
/* Add smooth scrolling behavior */
|
||||
html {
|
||||
scroll-behavior: smooth;
|
||||
}
|
||||
|
||||
body {
|
||||
font-family: var(--font-family-primary), serif;
|
||||
background-color: var(--color-background);
|
||||
color: var(--color-text);
|
||||
line-height: var(--line-height);
|
||||
}
|
||||
|
||||
/* === Container für zentralen Content === */
|
||||
.container {
|
||||
max-width: var(--container-max-width);
|
||||
width: var(--container-width);
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
|
||||
a {
|
||||
color: #ffa500;
|
||||
}
|
||||
|
||||
a:hover {
|
||||
text-decoration: none;
|
||||
}
|
||||
34
styles/variables.css
Normal file
@ -0,0 +1,34 @@
|
||||
:root {
|
||||
/* Colors */
|
||||
--color-background: #000;
|
||||
--color-text: #f5f5f5;
|
||||
--color-accent-green: #213b28;
|
||||
--color-accent-beige: #ceb39b;
|
||||
--color-accent-green-transparent: rgba(33, 59, 40, 0.95);
|
||||
--color-shadow: rgba(0, 0, 0, 0.2);
|
||||
--color-orange1: #ffa500;
|
||||
|
||||
/* Font Sizes */
|
||||
--font-family-primary: 'Georgia', serif;
|
||||
--font-size-small: 1rem;
|
||||
--font-size-small-medium: 1.2rem;
|
||||
--font-size-medium: 1.5rem;
|
||||
--font-size-large: 2rem;
|
||||
--line-height: 1.6;
|
||||
|
||||
|
||||
--container-width: 100%;
|
||||
--container-max-width: 1600px;
|
||||
--padding-vertical: 2rem;
|
||||
--padding-horizontal: 0;
|
||||
--margin-standard: 1rem;
|
||||
--gap-standard: 30px;
|
||||
|
||||
--border-radius: 8px;
|
||||
--box-shadow: 0 4px 8px var(--color-shadow);
|
||||
--transition-standard: 0.3s ease;
|
||||
|
||||
|
||||
--breakpoint-mobile: 768px;
|
||||
--breakpoint-desktop: 1600px;
|
||||
}
|
||||
5
tsconfig.json
Normal file
@ -0,0 +1,5 @@
|
||||
{
|
||||
"extends": "astro/tsconfigs/strict",
|
||||
"include": [".astro/types.d.ts", "**/*"],
|
||||
"exclude": ["dist"]
|
||||
}
|
||||