initial
This commit is contained in:
3
Dockerfile
Normal file
3
Dockerfile
Normal file
@@ -0,0 +1,3 @@
|
||||
FROM nginx:alpine
|
||||
COPY index.html /usr/share/nginx/html/index.html
|
||||
COPY logo.png /usr/share/nginx/html/logo.png
|
||||
18
docker-compose.yml
Normal file
18
docker-compose.yml
Normal file
@@ -0,0 +1,18 @@
|
||||
services:
|
||||
meineordi-web:
|
||||
build: .
|
||||
container_name: meineordi-web
|
||||
restart: unless-stopped
|
||||
ports:
|
||||
- "8080:80"
|
||||
healthcheck:
|
||||
test: ["CMD", "wget", "-qO-", "http://localhost/"]
|
||||
interval: 30s
|
||||
timeout: 5s
|
||||
retries: 3
|
||||
networks:
|
||||
- nginx_internal_network
|
||||
|
||||
networks:
|
||||
nginx_internal_network:
|
||||
external: true
|
||||
28
gitea-stack.yml
Normal file
28
gitea-stack.yml
Normal file
@@ -0,0 +1,28 @@
|
||||
services:
|
||||
gitea:
|
||||
image: gitea/gitea:latest
|
||||
container_name: gitea
|
||||
restart: unless-stopped
|
||||
environment:
|
||||
USER_UID: "1000"
|
||||
USER_GID: "1000"
|
||||
GITEA__database__DB_TYPE: sqlite3
|
||||
GITEA__server__DOMAIN: git.stranto.com
|
||||
GITEA__server__ROOT_URL: http://git.stranto.com
|
||||
GITEA__server__SSH_DOMAIN: git.stranto.com
|
||||
volumes:
|
||||
- gitea-data:/data
|
||||
- /etc/timezone:/etc/timezone:ro
|
||||
- /etc/localtime:/etc/localtime:ro
|
||||
ports:
|
||||
- "3000:3000"
|
||||
- "222:22"
|
||||
networks:
|
||||
nginx_internal_network: {}
|
||||
|
||||
volumes:
|
||||
gitea-data:
|
||||
|
||||
networks:
|
||||
nginx_internal_network:
|
||||
external: true
|
||||
781
index.html
Normal file
781
index.html
Normal file
@@ -0,0 +1,781 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="de">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<meta name="description" content="Dr. med. Carina Kautsch – Ärztin für Allgemeinmedizin in 1160 Wien. Öffnungszeiten, Leistungen und Kontakt." />
|
||||
<title>Dr. Carina Kautsch – Allgemeinmedizin Wien</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=Cormorant+Garamond:ital,wght@0,400;0,600;0,700;1,400&family=DM+Sans:wght@400;500;600&display=swap" rel="stylesheet" />
|
||||
<style>
|
||||
/* ─── Reset & Base ─────────────────────────────────────── */
|
||||
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
|
||||
html { scroll-behavior: smooth; }
|
||||
body {
|
||||
font-family: 'DM Sans', sans-serif;
|
||||
font-size: 18px;
|
||||
color: #222;
|
||||
background: #fff;
|
||||
line-height: 1.6;
|
||||
}
|
||||
a { color: inherit; text-decoration: none; }
|
||||
img { display: block; max-width: 100%; }
|
||||
|
||||
/* ─── Variables ─────────────────────────────────────────── */
|
||||
:root {
|
||||
--red: #C8102E;
|
||||
--red-dk: #a00d24;
|
||||
--bg-alt: #f7f7f7;
|
||||
--shadow: 0 6px 28px rgba(0,0,0,.14);
|
||||
--radius: 12px;
|
||||
}
|
||||
|
||||
/* ─── Animations ────────────────────────────────────────── */
|
||||
@keyframes fadeUp {
|
||||
from { opacity: 0; transform: translateY(24px); }
|
||||
to { opacity: 1; transform: translateY(0); }
|
||||
}
|
||||
@keyframes floatLogo {
|
||||
0%, 100% { transform: translateY(0); }
|
||||
50% { transform: translateY(-12px); }
|
||||
}
|
||||
|
||||
/* ─── Header / Nav ──────────────────────────────────────── */
|
||||
header {
|
||||
position: sticky;
|
||||
top: 0;
|
||||
z-index: 100;
|
||||
background: #fff;
|
||||
border-bottom: 1px solid #eee;
|
||||
box-shadow: 0 2px 12px rgba(0,0,0,.07);
|
||||
}
|
||||
nav {
|
||||
max-width: 1100px;
|
||||
margin: 0 auto;
|
||||
padding: 0 24px;
|
||||
height: 68px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
gap: 16px;
|
||||
}
|
||||
.nav-logo img { height: 42px; width: auto; }
|
||||
.nav-links {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 28px;
|
||||
list-style: none;
|
||||
}
|
||||
.nav-links a {
|
||||
font-size: 15px;
|
||||
font-weight: 500;
|
||||
color: #444;
|
||||
transition: color .2s;
|
||||
}
|
||||
.nav-links a:hover { color: var(--red); }
|
||||
.nav-phone {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
background: var(--red);
|
||||
color: #fff;
|
||||
font-weight: 600;
|
||||
font-size: 15px;
|
||||
padding: 9px 18px;
|
||||
border-radius: 8px;
|
||||
white-space: nowrap;
|
||||
transition: background .2s;
|
||||
}
|
||||
.nav-phone:hover { background: var(--red-dk); }
|
||||
|
||||
/* Hamburger */
|
||||
.hamburger {
|
||||
display: none;
|
||||
flex-direction: column;
|
||||
gap: 5px;
|
||||
cursor: pointer;
|
||||
background: none;
|
||||
border: none;
|
||||
padding: 4px;
|
||||
}
|
||||
.hamburger span {
|
||||
display: block;
|
||||
width: 26px;
|
||||
height: 2px;
|
||||
background: #333;
|
||||
border-radius: 2px;
|
||||
transition: all .3s;
|
||||
}
|
||||
.hamburger.open span:nth-child(1) { transform: rotate(45deg) translate(5px, 5px); }
|
||||
.hamburger.open span:nth-child(2) { opacity: 0; }
|
||||
.hamburger.open span:nth-child(3) { transform: rotate(-45deg) translate(5px, -5px); }
|
||||
|
||||
.mobile-menu {
|
||||
display: none;
|
||||
flex-direction: column;
|
||||
background: #fff;
|
||||
border-top: 1px solid #eee;
|
||||
padding: 16px 24px 20px;
|
||||
gap: 16px;
|
||||
}
|
||||
.mobile-menu.open { display: flex; }
|
||||
.mobile-menu a {
|
||||
font-size: 17px;
|
||||
font-weight: 500;
|
||||
color: #333;
|
||||
padding: 6px 0;
|
||||
border-bottom: 1px solid #f0f0f0;
|
||||
}
|
||||
.mobile-menu a:last-child { border-bottom: none; }
|
||||
.mobile-menu .nav-phone {
|
||||
margin-top: 4px;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
/* ─── Section Helpers ───────────────────────────────────── */
|
||||
section { padding: 72px 24px; }
|
||||
section.alt { background: var(--bg-alt); }
|
||||
.section-inner {
|
||||
max-width: 1100px;
|
||||
margin: 0 auto;
|
||||
}
|
||||
.section-title {
|
||||
font-family: 'Cormorant Garamond', serif;
|
||||
font-size: clamp(2rem, 4vw, 2.8rem);
|
||||
font-weight: 700;
|
||||
color: var(--red);
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
.section-sub {
|
||||
font-size: 16px;
|
||||
color: #666;
|
||||
margin-bottom: 40px;
|
||||
}
|
||||
|
||||
/* ─── Hero ──────────────────────────────────────────────── */
|
||||
#hero {
|
||||
padding: 80px 24px 60px;
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
min-height: 520px;
|
||||
}
|
||||
.hero-watermark {
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
width: 480px;
|
||||
opacity: .04;
|
||||
pointer-events: none;
|
||||
user-select: none;
|
||||
}
|
||||
.hero-inner {
|
||||
max-width: 1100px;
|
||||
margin: 0 auto;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 48px;
|
||||
position: relative;
|
||||
}
|
||||
.hero-text {
|
||||
flex: 1;
|
||||
animation: fadeUp .7s ease both;
|
||||
}
|
||||
.hero-text h1 {
|
||||
font-family: 'Cormorant Garamond', serif;
|
||||
font-size: clamp(2.4rem, 5vw, 3.6rem);
|
||||
font-weight: 700;
|
||||
line-height: 1.15;
|
||||
color: #111;
|
||||
margin-bottom: 12px;
|
||||
}
|
||||
.hero-text h1 span { color: var(--red); }
|
||||
.hero-text p {
|
||||
font-size: 18px;
|
||||
color: #555;
|
||||
margin-bottom: 32px;
|
||||
max-width: 480px;
|
||||
}
|
||||
.hero-cta {
|
||||
display: flex;
|
||||
gap: 14px;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
.btn {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
padding: 13px 26px;
|
||||
border-radius: 9px;
|
||||
font-size: 16px;
|
||||
font-weight: 600;
|
||||
transition: all .2s;
|
||||
cursor: pointer;
|
||||
border: none;
|
||||
}
|
||||
.btn-primary { background: var(--red); color: #fff; }
|
||||
.btn-primary:hover { background: var(--red-dk); transform: translateY(-2px); }
|
||||
.btn-outline { background: transparent; color: var(--red); border: 2px solid var(--red); }
|
||||
.btn-outline:hover { background: var(--red); color: #fff; transform: translateY(-2px); }
|
||||
|
||||
.hero-logo-wrap {
|
||||
flex-shrink: 0;
|
||||
animation: fadeUp .7s .2s ease both;
|
||||
}
|
||||
.hero-logo-wrap img {
|
||||
width: 280px;
|
||||
animation: floatLogo 4s ease-in-out infinite;
|
||||
}
|
||||
|
||||
.hero-cards {
|
||||
max-width: 1100px;
|
||||
margin: 48px auto 0;
|
||||
display: grid;
|
||||
grid-template-columns: repeat(4, 1fr);
|
||||
gap: 16px;
|
||||
animation: fadeUp .7s .35s ease both;
|
||||
}
|
||||
.hero-card {
|
||||
background: var(--bg-alt);
|
||||
border-radius: var(--radius);
|
||||
padding: 20px 18px;
|
||||
display: flex;
|
||||
align-items: flex-start;
|
||||
gap: 14px;
|
||||
}
|
||||
.hero-card-icon { font-size: 26px; line-height: 1; flex-shrink: 0; }
|
||||
.hero-card-label {
|
||||
font-size: 13px;
|
||||
color: #888;
|
||||
font-weight: 500;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: .04em;
|
||||
}
|
||||
.hero-card-value {
|
||||
font-size: 15px;
|
||||
font-weight: 600;
|
||||
color: #222;
|
||||
margin-top: 2px;
|
||||
}
|
||||
|
||||
/* ─── Öffnungszeiten ────────────────────────────────────── */
|
||||
.hours-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(2, 1fr);
|
||||
gap: 16px;
|
||||
max-width: 600px;
|
||||
}
|
||||
.hour-card {
|
||||
background: #fff;
|
||||
border-radius: var(--radius);
|
||||
box-shadow: var(--shadow);
|
||||
border-left: 4px solid var(--red);
|
||||
padding: 18px 22px;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
transition: transform .2s, box-shadow .2s;
|
||||
}
|
||||
.hour-card:hover { transform: translateY(-3px); box-shadow: 0 10px 36px rgba(0,0,0,.17); }
|
||||
.hour-day { font-weight: 600; color: #333; }
|
||||
.hour-time { color: var(--red); font-weight: 600; font-size: 15px; }
|
||||
.hour-closed { color: #aaa; font-style: italic; }
|
||||
|
||||
/* ─── Schließzeiten ─────────────────────────────────────── */
|
||||
#schliesszeiten .no-closures {
|
||||
background: #fff;
|
||||
border-radius: var(--radius);
|
||||
padding: 28px 28px;
|
||||
border: 2px dashed #ddd;
|
||||
color: #888;
|
||||
font-style: italic;
|
||||
max-width: 480px;
|
||||
}
|
||||
.closure-cards {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
|
||||
gap: 20px;
|
||||
}
|
||||
.closure-card {
|
||||
background: #fff;
|
||||
border-radius: var(--radius);
|
||||
box-shadow: var(--shadow);
|
||||
border-top: 4px solid var(--red);
|
||||
padding: 22px 24px;
|
||||
}
|
||||
.closure-dates {
|
||||
font-family: 'Cormorant Garamond', serif;
|
||||
font-size: 1.4rem;
|
||||
font-weight: 700;
|
||||
color: var(--red);
|
||||
margin-bottom: 4px;
|
||||
}
|
||||
.closure-reason {
|
||||
font-weight: 600;
|
||||
color: #333;
|
||||
margin-bottom: 12px;
|
||||
}
|
||||
.closure-deputy-label {
|
||||
font-size: 13px;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: .04em;
|
||||
color: #999;
|
||||
margin-bottom: 6px;
|
||||
}
|
||||
.closure-deputy-name { font-weight: 600; color: #222; margin-bottom: 2px; }
|
||||
.closure-deputy-detail { font-size: 15px; color: #555; line-height: 1.5; }
|
||||
|
||||
/* ─── Leistungen ────────────────────────────────────────── */
|
||||
.leistungen-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(3, 1fr);
|
||||
gap: 20px;
|
||||
}
|
||||
.leistung-card {
|
||||
background: #fff;
|
||||
border-radius: var(--radius);
|
||||
box-shadow: 0 3px 18px rgba(0,0,0,.08);
|
||||
padding: 28px 24px;
|
||||
transition: transform .2s, box-shadow .2s;
|
||||
}
|
||||
.leistung-card:hover { transform: translateY(-4px); box-shadow: 0 8px 30px rgba(0,0,0,.13); }
|
||||
.leistung-icon { font-size: 2.2rem; margin-bottom: 14px; }
|
||||
.leistung-title { font-weight: 700; font-size: 17px; margin-bottom: 8px; color: #222; }
|
||||
.leistung-desc { font-size: 15px; color: #666; line-height: 1.55; }
|
||||
|
||||
/* ─── Aktuelles ─────────────────────────────────────────── */
|
||||
.aktuelles-list {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 16px;
|
||||
max-width: 780px;
|
||||
}
|
||||
.aktuell-item {
|
||||
background: #fff;
|
||||
border-radius: var(--radius);
|
||||
box-shadow: 0 3px 18px rgba(0,0,0,.08);
|
||||
padding: 22px 26px;
|
||||
border-left: 4px solid var(--red);
|
||||
}
|
||||
.aktuell-title { font-weight: 700; color: #222; margin-bottom: 6px; font-size: 17px; }
|
||||
.aktuell-body { font-size: 15px; color: #555; line-height: 1.6; }
|
||||
|
||||
/* ─── Kontakt ────────────────────────────────────────────── */
|
||||
.kontakt-inner {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr 1fr;
|
||||
gap: 48px;
|
||||
align-items: start;
|
||||
}
|
||||
.kontakt-rows { display: flex; flex-direction: column; gap: 18px; }
|
||||
.kontakt-row {
|
||||
display: flex;
|
||||
align-items: flex-start;
|
||||
gap: 16px;
|
||||
}
|
||||
.kontakt-icon {
|
||||
font-size: 22px;
|
||||
flex-shrink: 0;
|
||||
margin-top: 2px;
|
||||
}
|
||||
.kontakt-label { font-size: 13px; color: #999; text-transform: uppercase; letter-spacing: .04em; margin-bottom: 2px; }
|
||||
.kontakt-value { font-size: 17px; font-weight: 500; color: #222; }
|
||||
.kontakt-value a:hover { color: var(--red); }
|
||||
.map-wrap {
|
||||
border-radius: var(--radius);
|
||||
overflow: hidden;
|
||||
box-shadow: var(--shadow);
|
||||
}
|
||||
.map-wrap iframe {
|
||||
width: 100%;
|
||||
height: 360px;
|
||||
border: 0;
|
||||
display: block;
|
||||
}
|
||||
|
||||
/* ─── Footer ────────────────────────────────────────────── */
|
||||
footer {
|
||||
background: #1a1a1a;
|
||||
color: #aaa;
|
||||
padding: 36px 24px;
|
||||
text-align: center;
|
||||
}
|
||||
.footer-inner {
|
||||
max-width: 1100px;
|
||||
margin: 0 auto;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
gap: 16px;
|
||||
}
|
||||
footer img { height: 38px; filter: brightness(0) invert(1); opacity: .7; }
|
||||
footer p { font-size: 14px; }
|
||||
footer a { color: #ccc; }
|
||||
footer a:hover { color: #fff; }
|
||||
|
||||
/* ─── Responsive ────────────────────────────────────────── */
|
||||
@media (max-width: 900px) {
|
||||
.leistungen-grid { grid-template-columns: repeat(2, 1fr); }
|
||||
.hero-cards { grid-template-columns: repeat(2, 1fr); }
|
||||
.kontakt-inner { grid-template-columns: 1fr; }
|
||||
}
|
||||
@media (max-width: 768px) {
|
||||
.nav-links, .nav-phone { display: none; }
|
||||
.hamburger { display: flex; }
|
||||
.hero-inner { flex-direction: column-reverse; text-align: center; }
|
||||
.hero-logo-wrap img { width: 180px; margin: 0 auto; }
|
||||
.hero-cta { justify-content: center; }
|
||||
.hero-text p { margin: 0 auto 32px; }
|
||||
.hours-grid { grid-template-columns: 1fr; }
|
||||
}
|
||||
@media (max-width: 540px) {
|
||||
.hero-cards { grid-template-columns: 1fr; }
|
||||
.leistungen-grid { grid-template-columns: 1fr; }
|
||||
section { padding: 52px 16px; }
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<!-- ═══════════════════════════════════════════════════════════
|
||||
SCHLIESSZEITEN — edit only this array to manage holidays
|
||||
═══════════════════════════════════════════════════════════ -->
|
||||
<script>
|
||||
const SCHLIESSZEITEN = [
|
||||
{
|
||||
dates: "30.3. – 3.4.",
|
||||
reason: "Karwoche",
|
||||
deputy: "Dr. Irene Lachawitz",
|
||||
deputyAddr: "1160 Wien, Neulerchenfelderstraße 14/6",
|
||||
deputyPhone: "01 / 406 31 04",
|
||||
deputyHours: "Mo & Mi 8–12 Uhr · Di & Do 14–18 Uhr · Fr 12–16 Uhr"
|
||||
},
|
||||
// Add more closures here:
|
||||
// {
|
||||
// dates: "DD.MM. – DD.MM.",
|
||||
// reason: "Urlaub",
|
||||
// deputy: "Dr. Vorname Nachname",
|
||||
// deputyAddr: "1160 Wien, Musterstraße 1",
|
||||
// deputyPhone: "01 / 000 00 00",
|
||||
// deputyHours: "Mo–Fr 8–12 Uhr"
|
||||
// },
|
||||
];
|
||||
</script>
|
||||
|
||||
<!-- ─── Header ───────────────────────────────────────────── -->
|
||||
<header>
|
||||
<nav>
|
||||
<a class="nav-logo" href="#hero">
|
||||
<img src="/logo.png" alt="meineOrdi Logo" />
|
||||
</a>
|
||||
<ul class="nav-links">
|
||||
<li><a href="#oeffnungszeiten">Öffnungszeiten</a></li>
|
||||
<li><a href="#leistungen">Leistungen</a></li>
|
||||
<li><a href="#aktuelles">Aktuelles</a></li>
|
||||
<li><a href="#kontakt">Kontakt</a></li>
|
||||
</ul>
|
||||
<a class="nav-phone" href="tel:+4314931773">
|
||||
📞 +43 1 493 17 73
|
||||
</a>
|
||||
<button class="hamburger" id="hamburger" aria-label="Menü öffnen">
|
||||
<span></span><span></span><span></span>
|
||||
</button>
|
||||
</nav>
|
||||
<div class="mobile-menu" id="mobile-menu">
|
||||
<a href="#oeffnungszeiten">Öffnungszeiten</a>
|
||||
<a href="#leistungen">Leistungen</a>
|
||||
<a href="#aktuelles">Aktuelles</a>
|
||||
<a href="#kontakt">Kontakt</a>
|
||||
<a class="nav-phone" href="tel:+4314931773">📞 +43 1 493 17 73</a>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<!-- ─── Hero ─────────────────────────────────────────────── -->
|
||||
<section id="hero">
|
||||
<img class="hero-watermark"
|
||||
src="/logo.png"
|
||||
alt="" aria-hidden="true" />
|
||||
<div class="hero-inner">
|
||||
<div class="hero-text">
|
||||
<h1>Ihre Ärztin für<br><span>Allgemeinmedizin</span><br>in Wien</h1>
|
||||
<p>Dr. med. Carina Kautsch – persönliche, umfassende medizinische Betreuung in 1160 Wien.</p>
|
||||
<div class="hero-cta">
|
||||
<a class="btn btn-primary" href="tel:+4314931773">📞 Jetzt anrufen</a>
|
||||
<a class="btn btn-outline" href="#oeffnungszeiten">Öffnungszeiten</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="hero-logo-wrap">
|
||||
<img src="/logo.png" alt="meineOrdi" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="hero-cards">
|
||||
<div class="hero-card">
|
||||
<div class="hero-card-icon">📍</div>
|
||||
<div>
|
||||
<div class="hero-card-label">Adresse</div>
|
||||
<div class="hero-card-value">Pfenninggeldgasse 1B/3<br>A-1160 Wien</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="hero-card">
|
||||
<div class="hero-card-icon">📞</div>
|
||||
<div>
|
||||
<div class="hero-card-label">Telefon</div>
|
||||
<div class="hero-card-value">+43 / 1 / 493 17 73</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="hero-card">
|
||||
<div class="hero-card-icon">✉️</div>
|
||||
<div>
|
||||
<div class="hero-card-label">E-Mail</div>
|
||||
<div class="hero-card-value">info@meineordi.at</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="hero-card">
|
||||
<div class="hero-card-icon">🕐</div>
|
||||
<div>
|
||||
<div class="hero-card-label">Heute</div>
|
||||
<div class="hero-card-value" id="todays-hours">–</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- ─── Öffnungszeiten ────────────────────────────────────── -->
|
||||
<section id="oeffnungszeiten" class="alt">
|
||||
<div class="section-inner">
|
||||
<h2 class="section-title">Öffnungszeiten</h2>
|
||||
<p class="section-sub">Bitte vereinbaren Sie telefonisch einen Termin.</p>
|
||||
<div class="hours-grid">
|
||||
<div class="hour-card">
|
||||
<span class="hour-day">Montag</span>
|
||||
<span class="hour-time">14:00 – 19:00</span>
|
||||
</div>
|
||||
<div class="hour-card">
|
||||
<span class="hour-day">Dienstag</span>
|
||||
<span class="hour-time">14:00 – 18:00</span>
|
||||
</div>
|
||||
<div class="hour-card">
|
||||
<span class="hour-day">Mittwoch</span>
|
||||
<span class="hour-time">07:30 – 11:30</span>
|
||||
</div>
|
||||
<div class="hour-card">
|
||||
<span class="hour-day">Donnerstag</span>
|
||||
<span class="hour-time">13:00 – 17:00</span>
|
||||
</div>
|
||||
<div class="hour-card">
|
||||
<span class="hour-day">Freitag</span>
|
||||
<span class="hour-time">09:00 – 12:00</span>
|
||||
</div>
|
||||
<div class="hour-card">
|
||||
<span class="hour-day">Sa / So</span>
|
||||
<span class="hour-closed">geschlossen</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- ─── Schließzeiten ─────────────────────────────────────── -->
|
||||
<section id="schliesszeiten">
|
||||
<div class="section-inner">
|
||||
<h2 class="section-title">Schließzeiten</h2>
|
||||
<p class="section-sub">Vertretung während der Abwesenheit</p>
|
||||
<div id="closure-container"></div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- ─── Leistungen ────────────────────────────────────────── -->
|
||||
<section id="leistungen" class="alt">
|
||||
<div class="section-inner">
|
||||
<h2 class="section-title">Leistungen</h2>
|
||||
<p class="section-sub">Umfassende allgemeinmedizinische Versorgung für die ganze Familie.</p>
|
||||
<div class="leistungen-grid">
|
||||
<div class="leistung-card">
|
||||
<div class="leistung-icon">🩺</div>
|
||||
<div class="leistung-title">Allgemeine Untersuchung</div>
|
||||
<div class="leistung-desc">Vorsorgeuntersuchungen, Gesundencheck und allgemeine Diagnostik.</div>
|
||||
</div>
|
||||
<div class="leistung-card">
|
||||
<div class="leistung-icon">💊</div>
|
||||
<div class="leistung-title">Rezepte & Überweisungen</div>
|
||||
<div class="leistung-desc">Ausstellung von Rezepten, Überweisungen und ärztlichen Attesten.</div>
|
||||
</div>
|
||||
<div class="leistung-card">
|
||||
<div class="leistung-icon">🩸</div>
|
||||
<div class="leistung-title">Laboruntersuchungen</div>
|
||||
<div class="leistung-desc">Blutabnahme und Auswertung gängiger Laborparameter direkt in der Ordination.</div>
|
||||
</div>
|
||||
<div class="leistung-card">
|
||||
<div class="leistung-icon">❤️</div>
|
||||
<div class="leistung-title">Chronische Erkrankungen</div>
|
||||
<div class="leistung-desc">Langzeitbetreuung bei Diabetes, Bluthochdruck, Schilddrüsenerkrankungen u. v. m.</div>
|
||||
</div>
|
||||
<div class="leistung-card">
|
||||
<div class="leistung-icon">🌡️</div>
|
||||
<div class="leistung-title">Akutbehandlung</div>
|
||||
<div class="leistung-desc">Behandlung akuter Erkrankungen und Verletzungen, Krankmeldungen.</div>
|
||||
</div>
|
||||
<div class="leistung-card">
|
||||
<div class="leistung-icon">💉</div>
|
||||
<div class="leistung-title">Impfungen</div>
|
||||
<div class="leistung-desc">Reise- und Standardimpfungen nach aktuellem Impfplan.</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- ─── Aktuelles ─────────────────────────────────────────── -->
|
||||
<section id="aktuelles">
|
||||
<div class="section-inner">
|
||||
<h2 class="section-title">Aktuelles</h2>
|
||||
<p class="section-sub">Wichtige Hinweise aus der Ordination</p>
|
||||
<div class="aktuelles-list">
|
||||
<div class="aktuell-item">
|
||||
<div class="aktuell-title">Rezeptbestellung</div>
|
||||
<div class="aktuell-body">
|
||||
Rezepte für Dauermedikamente können telefonisch oder per E-Mail bestellt werden.
|
||||
Bitte geben Sie Name, Geburtsdatum und die gewünschten Medikamente an.
|
||||
Die Abholung ist nach Vereinbarung möglich.
|
||||
</div>
|
||||
</div>
|
||||
<div class="aktuell-item">
|
||||
<div class="aktuell-title">Diabetiker-Bedarf</div>
|
||||
<div class="aktuell-body">
|
||||
Für die Verordnung von Diabetes-Hilfsmitteln (Teststreifen, Insulinnadeln etc.)
|
||||
ist ein aktuelles Laborbefund erforderlich. Bitte rechtzeitig einen Termin vereinbaren.
|
||||
</div>
|
||||
</div>
|
||||
<div class="aktuell-item">
|
||||
<div class="aktuell-title">Krankmeldungen</div>
|
||||
<div class="aktuell-body">
|
||||
Krankmeldungen werden nur nach persönlicher Untersuchung ausgestellt.
|
||||
Telefonische Krankschreibungen sind leider nicht möglich.
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- ─── Kontakt & Standort ────────────────────────────────── -->
|
||||
<section id="kontakt" class="alt">
|
||||
<div class="section-inner">
|
||||
<h2 class="section-title">Kontakt & Standort</h2>
|
||||
<p class="section-sub">Wir freuen uns auf Ihren Besuch.</p>
|
||||
<div class="kontakt-inner">
|
||||
<div class="kontakt-rows">
|
||||
<div class="kontakt-row">
|
||||
<div class="kontakt-icon">📍</div>
|
||||
<div>
|
||||
<div class="kontakt-label">Adresse</div>
|
||||
<div class="kontakt-value">Pfenninggeldgasse 1B/3<br>A-1160 Wien</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="kontakt-row">
|
||||
<div class="kontakt-icon">📞</div>
|
||||
<div>
|
||||
<div class="kontakt-label">Telefon</div>
|
||||
<div class="kontakt-value"><a href="tel:+4314931773">+43 / 1 / 493 17 73</a></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="kontakt-row">
|
||||
<div class="kontakt-icon">✉️</div>
|
||||
<div>
|
||||
<div class="kontakt-label">E-Mail</div>
|
||||
<div class="kontakt-value"><a href="mailto:info@meineordi.at">info@meineordi.at</a></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="kontakt-row">
|
||||
<div class="kontakt-icon">👩⚕️</div>
|
||||
<div>
|
||||
<div class="kontakt-label">Ärztin</div>
|
||||
<div class="kontakt-value">Dr. med. Carina Kautsch<br>Ärztin für Allgemeinmedizin</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="map-wrap">
|
||||
<iframe
|
||||
src="https://www.openstreetmap.org/export/embed.html?bbox=16.325%2C48.200%2C16.340%2C48.210&layer=mapnik&marker=48.2052%2C16.3317"
|
||||
title="Standort der Ordination"
|
||||
loading="lazy"
|
||||
allowfullscreen>
|
||||
</iframe>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- ─── Footer ────────────────────────────────────────────── -->
|
||||
<footer>
|
||||
<div class="footer-inner">
|
||||
<img src="/logo.png" alt="meineOrdi" />
|
||||
<p>
|
||||
© <span id="footer-year"></span> Dr. med. Carina Kautsch ·
|
||||
Ärztin für Allgemeinmedizin · 1160 Wien
|
||||
</p>
|
||||
<p style="font-size:13px;">
|
||||
<a href="#impressum">Impressum</a> · <a href="#datenschutz">Datenschutz</a>
|
||||
</p>
|
||||
</div>
|
||||
</footer>
|
||||
|
||||
<!-- ─── Scripts ───────────────────────────────────────────── -->
|
||||
<script>
|
||||
// Hamburger menu
|
||||
const hamburger = document.getElementById('hamburger');
|
||||
const mobileMenu = document.getElementById('mobile-menu');
|
||||
hamburger.addEventListener('click', () => {
|
||||
hamburger.classList.toggle('open');
|
||||
mobileMenu.classList.toggle('open');
|
||||
});
|
||||
mobileMenu.querySelectorAll('a').forEach(a => {
|
||||
a.addEventListener('click', () => {
|
||||
hamburger.classList.remove('open');
|
||||
mobileMenu.classList.remove('open');
|
||||
});
|
||||
});
|
||||
|
||||
// Footer year
|
||||
document.getElementById('footer-year').textContent = new Date().getFullYear();
|
||||
|
||||
// Today's hours in hero card
|
||||
(function() {
|
||||
const hours = {
|
||||
1: '14:00 – 19:00',
|
||||
2: '14:00 – 18:00',
|
||||
3: '07:30 – 11:30',
|
||||
4: '13:00 – 17:00',
|
||||
5: '09:00 – 12:00',
|
||||
};
|
||||
const day = new Date().getDay(); // 0=Sun, 1=Mon, …
|
||||
const el = document.getElementById('todays-hours');
|
||||
el.textContent = hours[day] || 'Geschlossen';
|
||||
})();
|
||||
|
||||
// Render closure cards
|
||||
function renderClosures() {
|
||||
const container = document.getElementById('closure-container');
|
||||
if (!SCHLIESSZEITEN || SCHLIESSZEITEN.length === 0) {
|
||||
container.innerHTML = '<p class="no-closures">Derzeit keine Schließzeiten geplant.</p>';
|
||||
return;
|
||||
}
|
||||
const cards = SCHLIESSZEITEN.map(c => `
|
||||
<div class="closure-card">
|
||||
<div class="closure-dates">${c.dates}</div>
|
||||
<div class="closure-reason">${c.reason}</div>
|
||||
<div class="closure-deputy-label">Vertretung</div>
|
||||
<div class="closure-deputy-name">${c.deputy}</div>
|
||||
<div class="closure-deputy-detail">
|
||||
${c.deputyAddr}<br>
|
||||
Tel: ${c.deputyPhone}<br>
|
||||
${c.deputyHours}
|
||||
</div>
|
||||
</div>
|
||||
`).join('');
|
||||
container.innerHTML = `<div class="closure-cards">${cards}</div>`;
|
||||
}
|
||||
renderClosures();
|
||||
</script>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
133
meineordi-project-summary.md
Normal file
133
meineordi-project-summary.md
Normal file
@@ -0,0 +1,133 @@
|
||||
# Project Summary: meineordi.at Website Redesign
|
||||
|
||||
## Overview
|
||||
Complete static HTML redesign of the medical practice website for **Dr. med. Carina Kautsch**, Ärztin für Allgemeinmedizin, replacing a Joomla 3 CMS with a single self-contained `index.html` file served via nginx in Docker.
|
||||
|
||||
**Live site (old):** https://meineordi.at/
|
||||
**Logo URL:** https://meineordi.at/images/meineordi/logo.png
|
||||
|
||||
---
|
||||
|
||||
## Practice Information
|
||||
|
||||
| Field | Value |
|
||||
|---|---|
|
||||
| Doctor | Dr. med. Carina Kautsch |
|
||||
| Specialty | Ärztin für Allgemeinmedizin |
|
||||
| Address | Pfenninggeldgasse 1B/3, A-1160 Wien |
|
||||
| Phone | +43 / 1 / 493 17 73 |
|
||||
| Email | info@meineordi.at |
|
||||
|
||||
### Opening Hours
|
||||
| Day | Hours |
|
||||
|---|---|
|
||||
| Montag | 14:00 – 19:00 |
|
||||
| Dienstag | 14:00 – 18:00 |
|
||||
| Mittwoch | 07:30 – 11:30 |
|
||||
| Donnerstag | 13:00 – 17:00 |
|
||||
| Freitag | 09:00 – 12:00 |
|
||||
| Sa / So | geschlossen |
|
||||
|
||||
---
|
||||
|
||||
## Current Deliverable
|
||||
|
||||
### File: `index.html`
|
||||
A single fully self-contained HTML file. No framework, no build step, no CMS.
|
||||
|
||||
**Sections (top to bottom):**
|
||||
1. Sticky header with logo + nav links + phone button
|
||||
2. Hero — logo image large on right, headline + CTA buttons left, 4 quick-info cards below
|
||||
3. Öffnungszeiten — 2-column grid of hour boxes with shadows
|
||||
4. Schließzeiten — dynamically rendered from JS array (see below)
|
||||
5. Leistungen — 6-item service grid with emoji icons
|
||||
6. Aktuelles — 3 notice items (prescriptions, diabetes supplies, sick notes)
|
||||
7. Kontakt & Standort — contact rows + embedded OpenStreetMap iframe
|
||||
8. Footer with logo
|
||||
|
||||
### Design Decisions
|
||||
- **Fonts:** Cormorant Garamond (headings/serif) + DM Sans (body), loaded from Google Fonts
|
||||
- **Primary color:** `#C8102E` (red from meineOrdi logo) — fixed, not auto-extracted
|
||||
- **Background:** Pure white `#ffffff`, alt-sections `#f7f7f7`
|
||||
- **Base font size:** 18px (deliberately larger for older patients)
|
||||
- **Opening hours boxes:** white cards with strong drop shadow (`box-shadow: 0 6px 28px rgba(0,0,0,.14)`) and subtle red border, hover lift effect
|
||||
- **Logo:** displayed in navbar (42px height), large in hero section (280px, float animation), subtle watermark behind hero, inverted white in footer
|
||||
- **Map:** OpenStreetMap embed — no Google API key required
|
||||
- **Mobile:** Fully responsive, hamburger menu below 768px, logo shifts above text on mobile
|
||||
- **Animations:** CSS `fadeUp` on hero elements, `floatLogo` on hero logo
|
||||
|
||||
### Closure/Holiday Management (no CMS needed)
|
||||
At the very top of `<body>` is a clearly commented JavaScript array:
|
||||
|
||||
```js
|
||||
const SCHLIESSZEITEN = [
|
||||
{
|
||||
dates: "30.3. – 3.4.",
|
||||
reason: "Karwoche",
|
||||
deputy: "Dr. Irene Lachawitz",
|
||||
deputyAddr: "1160 Wien, Neulerchenfelderstraße 14/6",
|
||||
deputyPhone: "01 / 406 31 04",
|
||||
deputyHours: "Mo & Mi 8–12 Uhr · Di & Do 14–18 Uhr · Fr 12–16 Uhr"
|
||||
},
|
||||
// ... more entries
|
||||
];
|
||||
```
|
||||
|
||||
The `renderClosures()` function at the bottom of the script reads this array and builds the closure cards dynamically. Empty array → "Keine Schließzeiten" message shown automatically. This is the ONLY place that needs editing to manage holidays.
|
||||
|
||||
---
|
||||
|
||||
## Docker Setup
|
||||
|
||||
### Files
|
||||
```
|
||||
meineordi-docker.tar.gz
|
||||
├── Dockerfile
|
||||
├── index.html
|
||||
└── docker-compose.yml
|
||||
```
|
||||
|
||||
### Dockerfile
|
||||
```dockerfile
|
||||
FROM nginx:alpine
|
||||
COPY index.html /usr/share/nginx/html/index.html
|
||||
```
|
||||
|
||||
### docker-compose.yml
|
||||
```yaml
|
||||
services:
|
||||
meineordi-web:
|
||||
image: meineordi-web:latest
|
||||
container_name: meineordi-web
|
||||
restart: unless-stopped
|
||||
ports:
|
||||
- "8080:80"
|
||||
healthcheck:
|
||||
test: ["CMD", "wget", "-qO-", "http://localhost/"]
|
||||
interval: 30s
|
||||
timeout: 5s
|
||||
retries: 3
|
||||
```
|
||||
|
||||
### Build & Deploy
|
||||
```bash
|
||||
# Build image (must be done on the Docker host)
|
||||
docker build -t meineordi-web:latest .
|
||||
|
||||
# Deploy via Portainer → Stacks → Add stack → paste docker-compose.yml
|
||||
# OR run directly:
|
||||
docker compose up -d
|
||||
```
|
||||
|
||||
**Note:** The image must be built locally on the Docker host (or pushed to a registry) before Portainer can use it. The compose file references `meineordi-web:latest` as a pre-built local image, not a registry image.
|
||||
|
||||
---
|
||||
|
||||
## Possible Next Steps / Open Items
|
||||
|
||||
- **Reverse proxy integration** — The compose file currently exposes port 8080 directly. If the server uses Nginx Proxy Manager, Traefik, or Caddy, the `ports:` mapping should be replaced with a shared Docker network and proxy labels/config.
|
||||
- **Registry/CI** — For easier updates, the image could be pushed to a private registry (e.g. Gitea with built-in registry, or Docker Hub) so Portainer can pull updates without SSH access.
|
||||
- **HTTPS / domain** — Point `meineordi.at` DNS to the new server and configure SSL termination at the reverse proxy level.
|
||||
- **Logo CORS** — The logo is loaded cross-origin from `meineordi.at`. Once the site is self-hosted, copy `logo.png` into the Docker image alongside `index.html` and reference it as `/logo.png` to avoid any cross-origin issues and eliminate the external dependency.
|
||||
- **Content updates** — All content (hours, notices, services) is hardcoded in `index.html`. If more frequent edits are needed, consider a simple JSON config file mounted as a Docker volume, or a minimal admin UI built on top.
|
||||
- **Imprint / Datenschutz** — Austrian law (ECG / DSGVO) requires an Impressum and Datenschutzerklärung. These pages don't exist yet.
|
||||
Reference in New Issue
Block a user