Improve practice website accessibility, contact links and imagery

This commit is contained in:
2026-10-14 12:11:01 +02:00
parent 4022e4adb6
commit 5f70e543e5
10 changed files with 383 additions and 774 deletions
+3
View File
@@ -2,5 +2,8 @@ FROM nginx:alpine
COPY index.html /usr/share/nginx/html/index.html
COPY impressum.html /usr/share/nginx/html/impressum.html
COPY logo.png /usr/share/nginx/html/logo.png
COPY meineordi.png /usr/share/nginx/html/meineordi.png
COPY praxis-hero.png /usr/share/nginx/html/praxis-hero.png
COPY praxis-hero.webp praxis-hero-960.webp /usr/share/nginx/html/
COPY erster-besuch-abstrakt.webp /usr/share/nginx/html/erster-besuch-abstrakt.webp
COPY favicon.svg /usr/share/nginx/html/favicon.svg
+5
View File
@@ -0,0 +1,5 @@
Tool: built-in image_gen.
Original: erster-besuch-abstrakt.png
Web asset: erster-besuch-abstrakt.webp
Use case: stylized-concept. Asset type: abstract welcoming section image for 'Ihr erster Besuch' on a family medicine website. Primary request: a friendly, calming abstract composition suggesting openness, welcome and human connection, with no literal place. Style: sophisticated tactile paper sculpture with softly curved overlapping organic shapes and gentle flowing arcs, subtle fine paper grain and soft dimensional shadows. Color palette: warm ivory and cream, muted sage green and dusty teal, with one very small muted burgundy accent, harmonious and restrained. Lighting/mood: soft diffuse daylight, warm, approachable, reassuring. Composition: landscape 3:2, balanced spacious arrangement, softly rounded forms and clean generous margins, beautiful beside website text, no text baked into image. Constraints: entirely abstract; no rooms, no buildings, no doors, no furniture, no medical practice interiors, no people, no body parts, no medical equipment, no lettering, no symbols resembling a logo, no watermark.
Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 62 KiB

+91 -229
View File
@@ -27,141 +27,40 @@
/* ─── 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;
}
body { font-family: 'DM Sans', sans-serif; font-size: 18px; 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;
}
:root { --red: #C8102E; --red-dk: #a00d24; --bg-alt: #f7f7f7; --shadow: 0 6px 28px rgba(0,0,0,.14); }
/* ─── 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;
}
header { position: sticky; top: 0; z-index: 100; }
nav { margin: 0 auto; padding: 0 24px; display: flex; align-items: center; justify-content: space-between; gap: 16px; }
.nav-logo img { width: auto; }
.nav-links { display: flex; align-items: center; gap: 28px; list-style: none; }
.nav-links a { font-size: 15px; 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 { display: inline-flex; align-items: center; gap: 8px; background: var(--red); color: #fff; font-weight: 600; font-size: 15px; 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 { 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 { 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 { 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;
}
.mobile-menu .nav-phone { color: #fff; padding: 11px 18px; margin-top: 4px; justify-content: center; }
/* ─── Font Size Toggle ──────────────────────────────────── */
.font-toggle-wrap {
display: flex;
align-items: center;
gap: 4px;
flex-shrink: 0;
}
.font-toggle-wrap button {
background: none;
border: 2px solid #ddd;
border-radius: 7px;
cursor: pointer;
font-family: 'DM Sans', sans-serif;
font-weight: 700;
color: #666;
line-height: 1;
transition: all .2s;
padding: 5px 9px;
}
.font-toggle-wrap button.active {
border-color: var(--red);
color: var(--red);
background: #fff0f2;
}
.font-toggle-wrap { display: flex; align-items: center; gap: 4px; flex-shrink: 0; }
.font-toggle-wrap button { background: none; border: 2px solid #ddd; cursor: pointer; font-family: 'DM Sans', sans-serif; font-weight: 700; color: #666; line-height: 1; transition: all .2s; padding: 5px 9px; }
.font-toggle-wrap button.active { border-color: var(--red); color: var(--red); }
.font-toggle-wrap button:first-child { font-size: 14px; }
.font-toggle-wrap button:last-child { font-size: 18px; }
@@ -171,92 +70,37 @@
body.large-font .nav-phone { font-size: 17px; }
/* ─── 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;
}
.section-inner { margin: 0 auto; }
.section-sub { margin-bottom: 40px; }
/* ─── Impressum / Datenschutz ──────────────────────────── */
.legal-section h3 {
font-family: 'Cormorant Garamond', serif;
font-size: 1.4rem;
font-weight: 700;
color: var(--red);
margin: 32px 0 10px;
}
.legal-section h3 { font-weight: 700; margin: 32px 0 10px; }
.legal-section h3:first-of-type { margin-top: 0; }
.legal-section p, .legal-section li {
font-size: 16px;
color: #444;
line-height: 1.7;
margin-bottom: 8px;
}
.legal-section ul {
padding-left: 20px;
margin-bottom: 12px;
}
.legal-section p, .legal-section li { font-size: 16px; margin-bottom: 8px; }
.legal-section ul { padding-left: 20px; margin-bottom: 12px; }
.legal-section a { color: var(--red); text-decoration: underline; }
.legal-section .legal-box {
background: #fff;
border-radius: var(--radius);
border-left: 4px solid var(--red);
padding: 20px 24px;
margin-top: 8px;
}
.legal-section .legal-box { background: #fff; margin-top: 8px; }
body.large-font .legal-section p,
body.large-font .legal-section li { font-size: 18px; }
/* ─── Back link ─────────────────────────────────────────── */
.back-link {
display: inline-flex;
align-items: center;
gap: 6px;
color: var(--red);
font-weight: 600;
font-size: 15px;
margin-bottom: 32px;
text-decoration: none;
transition: color .2s;
}
.back-link { display: inline-flex; align-items: center; gap: 6px; color: var(--red); font-weight: 600; font-size: 15px; text-decoration: none; transition: color .2s; }
.back-link:hover { color: var(--red-dk); }
/* ─── 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 { text-align: center; }
.footer-inner { max-width: 1100px; margin: 0 auto; display: flex; flex-direction: column; align-items: center; gap: 16px; }
footer p { font-size: 14px; }
footer a { color: #ccc; }
footer a:hover { color: #fff; }
/* ─── Responsive ────────────────────────────────────────── */
@media (max-width: 768px) {
.nav-links, .nav-phone { display: none; }
.nav-links, nav > .nav-phone { display: none; }
.hamburger { display: flex; }
}
@media (max-width: 540px) {
@@ -264,24 +108,11 @@
}
/* ─── 2026 visual refresh ──────────────────────────────── */
:root {
--ink: #20302c;
--muted: #66736f;
--sage: #e9f1ec;
--cream: #fbf8f3;
--red-soft: #f9e9ec;
--line: rgba(32, 48, 44, .11);
--radius: 20px;
}
:root { --ink: #20302c; --muted: #66736f; --sage: #e9f1ec; --cream: #fbf8f3; --red-soft: #f9e9ec; --line: rgba(32, 48, 44, .11); --radius: 20px; }
body { color: var(--ink); background: var(--cream); }
header {
background: rgba(255,255,255,.94);
border-bottom: 1px solid rgba(32,48,44,.08);
box-shadow: 0 8px 30px rgba(35,55,48,.06);
backdrop-filter: blur(16px);
}
header { background: rgba(255,255,255,.94); border-bottom: 1px solid rgba(32,48,44,.08); box-shadow: 0 8px 30px rgba(35,55,48,.06); backdrop-filter: blur(16px); }
nav { max-width: 1180px; height: 82px; }
.nav-logo img { height: 48px; }
.nav-logo img { height: 64px; }
.nav-links a { color: #41504c; font-weight: 600; }
.nav-phone { border-radius: 999px; padding: 11px 18px; box-shadow: 0 8px 22px rgba(200,16,46,.20); }
.nav-phone svg { width: 19px; height: 19px; fill: none; stroke: currentColor; stroke-width: 2; }
@@ -290,15 +121,7 @@
section { padding: 90px 24px; scroll-margin-top: 82px; }
section.alt { background: #f3f6f3; }
.section-inner { max-width: 920px; }
.section-title {
font-family: 'DM Sans', sans-serif;
color: var(--ink);
font-size: clamp(2.2rem, 5vw, 3.3rem);
font-weight: 600;
line-height: 1.1;
letter-spacing: -.04em;
margin-bottom: 12px;
}
.section-title { font-family: 'DM Sans', sans-serif; color: var(--ink); font-size: clamp(2.2rem, 5vw, 3.3rem); font-weight: 600; line-height: 1.1; letter-spacing: -.04em; margin-bottom: 12px; }
.section-title::before { content: ''; display: block; width: 42px; height: 4px; margin-bottom: 20px; border-radius: 999px; background: var(--red); }
.section-sub { color: var(--muted); font-size: 17px; }
.legal-section h3 { font-family: 'DM Sans', sans-serif; color: var(--ink); font-size: 1.25rem; letter-spacing: -.015em; margin-top: 42px; }
@@ -306,27 +129,43 @@
.legal-section .legal-box { padding: 26px 28px; border: 1px solid var(--line); border-left: 4px solid var(--red); border-radius: var(--radius); box-shadow: 0 12px 32px rgba(35,55,48,.07); }
.back-link { padding: 8px 14px; margin-bottom: 38px; border-radius: 999px; background: var(--red-soft); }
footer { padding: 50px 24px; background: #21332e; color: #bfd0c8; }
footer img { height: 44px; opacity: .88; }
footer img { display: block; box-sizing: content-box; height: 60px; width: auto; padding: 12px 18px; border-radius: 12px; background: #fff; filter: none; opacity: 1; }
footer a { color: #eef4f1; }
@media (max-width: 768px) {
nav { height: 72px; padding: 0 20px; }
.mobile-menu { padding: 20px; box-shadow: 0 18px 30px rgba(35,55,48,.10); }
section { padding: 70px 20px; }
}
@media (max-width: 540px) { section { padding: 60px 16px; } }
@media (max-width: 540px) {
section { padding: 60px 16px; }
.nav-logo img { height: 56px; }
}
@media (prefers-reduced-motion: reduce) {
html { scroll-behavior: auto; }
*, *::before, *::after { transition-duration: .01ms !important; }
}
/* Keyboard navigation and patient information */
:focus-visible { outline: 3px solid #C8102E; outline-offset: 4px; }
.skip-link { position: fixed; top: 8px; left: 16px; z-index: 200; padding: 12px 18px; background: #fff; color: #20302c; border-radius: 8px; transform: translateY(-160%); }
.skip-link:focus { transform: translateY(0); }
.hamburger { min-width: 44px; min-height: 44px; align-items: center; justify-content: center; }
.font-toggle-wrap button { min-width: 44px; min-height: 44px; }
.hero-card-value a { text-decoration: none; }
.hero-card-value a:hover { color: var(--red); }
.first-visit { max-width: 780px; }
.first-visit p { margin-bottom: 16px; }
.first-visit a { text-decoration: underline; text-underline-offset: 3px; }
</style>
</head>
<body>
<a class="skip-link" href="#main-content">Zum Inhalt springen</a>
<!-- ─── Header ───────────────────────────────────────────── -->
<header>
<nav>
<a class="nav-logo" href="/">
<img src="/logo.png" alt="meineOrdi Logo" />
<img src="/meineordi.png" alt="meineOrdi Logo" />
</a>
<ul class="nav-links">
<li><a href="/#oeffnungszeiten">Öffnungszeiten</a></li>
@@ -335,14 +174,14 @@
<li><a href="/#kontakt">Kontakt</a></li>
</ul>
<div class="font-toggle-wrap" aria-label="Schriftgröße">
<button id="font-normal" title="Normale Schriftgröße">A</button>
<button id="font-large" title="Große Schriftgröße">A+</button>
<button id="font-normal" title="Normale Schriftgröße" aria-pressed="false">A</button>
<button id="font-large" title="Große Schriftgröße" aria-pressed="false">A+</button>
</div>
<a class="nav-phone" href="tel:+4314931773">
<svg viewBox="0 0 24 24" aria-hidden="true"><path d="M22 16.92v3a2 2 0 0 1-2.18 2 19.8 19.8 0 0 1-8.63-3.07 19.5 19.5 0 0 1-6-6A19.8 19.8 0 0 1 2.12 4.18 2 2 0 0 1 4.11 2h3a2 2 0 0 1 2 1.72c.12.9.33 1.78.62 2.63a2 2 0 0 1-.45 2.11L8 9.73a16 16 0 0 0 6 6l1.27-1.27a2 2 0 0 1 2.11-.45c.85.29 1.73.5 2.63.62A2 2 0 0 1 22 16.92z"/></svg>
+43 1 493 17 73
</a>
<button class="hamburger" id="hamburger" aria-label="Menü öffnen">
<button class="hamburger" id="hamburger" aria-label="Menü öffnen" aria-expanded="false" aria-controls="mobile-menu">
<span></span><span></span><span></span>
</button>
</nav>
@@ -353,17 +192,18 @@
<a href="/#kontakt">Kontakt</a>
<a class="nav-phone" href="tel:+4314931773"><svg viewBox="0 0 24 24" aria-hidden="true"><path d="M22 16.92v3a2 2 0 0 1-2.18 2 19.8 19.8 0 0 1-8.63-3.07 19.5 19.5 0 0 1-6-6A19.8 19.8 0 0 1 2.12 4.18 2 2 0 0 1 4.11 2h3a2 2 0 0 1 2 1.72c.12.9.33 1.78.62 2.63a2 2 0 0 1-.45 2.11L8 9.73a16 16 0 0 0 6 6l1.27-1.27a2 2 0 0 1 2.11-.45c.85.29 1.73.5 2.63.62A2 2 0 0 1 22 16.92z"/></svg> +43 1 493 17 73</a>
<div class="font-toggle-wrap" style="justify-content:center;">
<button id="font-normal-mobile" title="Normale Schriftgröße">A</button>
<button id="font-large-mobile" title="Große Schriftgröße">A+</button>
<button id="font-normal-mobile" title="Normale Schriftgröße" aria-pressed="false">A</button>
<button id="font-large-mobile" title="Große Schriftgröße" aria-pressed="false">A+</button>
</div>
</div>
</header>
<main id="main-content" tabindex="-1">
<!-- ─── Impressum ────────────────────────────────────────── -->
<section id="impressum">
<div class="section-inner legal-section">
<a class="back-link" href="/">&#8592; Zurück zur Startseite</a>
<h2 class="section-title">Impressum</h2>
<h1 class="section-title">Impressum</h1>
<p class="section-sub">Angaben gemäß §5 ECG und §25 MedienG</p>
<h3>Diensteanbieter</h3>
@@ -545,9 +385,10 @@
</section>
<!-- ─── Footer ────────────────────────────────────────────── -->
</main>
<footer>
<div class="footer-inner">
<img src="/logo.png" alt="meineOrdi" />
<img src="/meineordi.png" alt="meineOrdi" />
<p>
&copy; <span id="footer-year"></span> Dr. med. Carina Kautsch &nbsp;·&nbsp;
Ärztin für Allgemeinmedizin &nbsp;·&nbsp; 1160 Wien
@@ -563,14 +404,30 @@
// Hamburger menu
const hamburger = document.getElementById('hamburger');
const mobileMenu = document.getElementById('mobile-menu');
hamburger.addEventListener('click', () => {
hamburger.classList.toggle('open');
mobileMenu.classList.toggle('open');
function setMenuOpen(open) {
hamburger.classList.toggle('open', open);
mobileMenu.classList.toggle('open', open);
hamburger.setAttribute('aria-expanded', String(open));
hamburger.setAttribute('aria-label', open ? 'Menü schließen' : 'Menü öffnen');
}
hamburger.addEventListener('click', () => setMenuOpen(hamburger.getAttribute('aria-expanded') !== 'true'));
document.addEventListener('keydown', event => {
if (event.key === 'Escape' && hamburger.getAttribute('aria-expanded') === 'true') {
setMenuOpen(false);
hamburger.focus();
}
});
window.matchMedia('(min-width: 769px)').addEventListener('change', event => {
if (event.matches) setMenuOpen(false);
});
mobileMenu.querySelectorAll('a').forEach(a => {
a.addEventListener('click', () => {
hamburger.classList.remove('open');
mobileMenu.classList.remove('open');
setMenuOpen(false);
const target = document.getElementById(a.hash.slice(1));
if (target && a.pathname === window.location.pathname) {
target.setAttribute('tabindex', '-1');
target.focus({ preventScroll: true });
}
});
});
@@ -591,10 +448,15 @@
btnLrg.classList.toggle('active', large);
btnNormM.classList.toggle('active', !large);
btnLrgM.classList.toggle('active', large);
localStorage.setItem('fontSize', large ? 'large' : 'normal');
[btnNorm, btnNormM].forEach(button => button.setAttribute('aria-pressed', String(!large)));
[btnLrg, btnLrgM].forEach(button => button.setAttribute('aria-pressed', String(large)));
try { localStorage.setItem('fontSize', large ? 'large' : 'normal'); } catch {}
}
setSize(localStorage.getItem('fontSize') === 'large');
let savedLarge = false;
try { savedLarge = localStorage.getItem('fontSize') === 'large'; } catch {}
setSize(savedLarge);
btnNorm.addEventListener('click', () => setSize(false));
btnLrg.addEventListener('click', () => setSize(true));
+214 -545
View File
@@ -27,24 +27,12 @@
/* ─── 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;
}
body { font-family: 'DM Sans', sans-serif; font-size: 18px; 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;
}
:root { --red: #C8102E; --red-dk: #a00d24; --bg-alt: #f7f7f7; }
/* ─── Animations ────────────────────────────────────────── */
@keyframes fadeUp {
@@ -57,402 +45,113 @@
}
/* ─── 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;
}
header { position: sticky; top: 0; z-index: 100; }
nav { max-width: 1100px; margin: 0 auto; padding: 0 24px; display: flex; align-items: center; justify-content: space-between; gap: 16px; }
.nav-logo img { width: auto; }
.nav-links { display: flex; align-items: center; list-style: none; }
.nav-links a { 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 { display: inline-flex; align-items: center; gap: 8px; background: var(--red); color: #fff; font-weight: 600; font-size: 15px; 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 { 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 { 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 { 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;
}
.mobile-menu .nav-phone { padding: 11px 18px; margin-top: 4px; justify-content: center; color: #fff; }
/* ─── 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;
}
.section-inner { max-width: 1100px; margin: 0 auto; }
/* ─── 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;
}
#hero { position: relative; overflow: hidden; }
.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; align-items: center; gap: 48px; }
.hero-text { flex: 1; }
.hero-cta { display: flex; gap: 14px; flex-wrap: wrap; }
.btn { display: inline-flex; align-items: center; gap: 8px; 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 { 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-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-cards { max-width: 1100px; display: grid; grid-template-columns: repeat(4, 1fr); animation: fadeUp .7s .35s ease both; }
.hero-card { 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;
}
.hero-card-label { font-weight: 500; text-transform: uppercase; }
.hero-card-value { font-weight: 600; 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); }
.hours-grid { display: grid; grid-template-columns: repeat(2, 1fr); }
.hour-card { background: #fff; display: flex; justify-content: space-between; align-items: center; transition: transform .2s, box-shadow .2s; }
.hour-day { font-weight: 600; color: #333; }
.hour-time { color: var(--red); font-weight: 600; font-size: 15px; }
.hour-time { 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;
}
#schliesszeiten .no-closures { 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); padding: 22px 24px; }
.closure-dates { font-size: 1.4rem; font-weight: 700; 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; }
.leistungen-grid { display: grid; grid-template-columns: repeat(3, 1fr); }
.leistung-card { background: #fff; transition: transform .2s, box-shadow .2s; }
.leistung-icon { font-size: 2.2rem; }
.leistung-title { font-weight: 700; margin-bottom: 8px; }
.leistung-desc { 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; }
.aktuelles-list { flex-direction: column; }
.aktuell-title { font-weight: 700; }
.aktuell-body { font-size: 15px; 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-inner { display: grid; grid-template-columns: 1fr 1fr; }
.kontakt-rows { display: flex; flex-direction: column; }
.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; text-transform: uppercase; margin-bottom: 2px; }
.kontakt-value { font-size: 17px; font-weight: 500; }
.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;
}
.map-wrap { overflow: hidden; }
.map-wrap iframe { width: 100%; 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 { text-align: center; }
.footer-inner { max-width: 1100px; margin: 0 auto; display: flex; flex-direction: column; align-items: center; gap: 16px; }
footer p { font-size: 14px; }
footer a { color: #ccc; }
footer a:hover { color: #fff; }
/* ─── Font Size Toggle ──────────────────────────────────── */
.font-toggle-wrap {
display: flex;
align-items: center;
gap: 4px;
flex-shrink: 0;
}
.font-toggle-wrap button {
background: none;
border: 2px solid #ddd;
border-radius: 7px;
cursor: pointer;
font-family: 'DM Sans', sans-serif;
font-weight: 700;
color: #666;
line-height: 1;
transition: all .2s;
padding: 5px 9px;
}
.font-toggle-wrap button.active {
border-color: var(--red);
color: var(--red);
background: #fff0f2;
}
.font-toggle-wrap { display: flex; align-items: center; gap: 4px; flex-shrink: 0; }
.font-toggle-wrap button { background: none; border: 2px solid #ddd; cursor: pointer; font-family: 'DM Sans', sans-serif; font-weight: 700; color: #666; line-height: 1; transition: all .2s; padding: 5px 9px; }
.font-toggle-wrap button.active { border-color: var(--red); color: var(--red); }
.font-toggle-wrap button:first-child { font-size: 14px; }
.font-toggle-wrap button:last-child { font-size: 18px; }
@@ -480,7 +179,7 @@
.kontakt-inner { grid-template-columns: 1fr; }
}
@media (max-width: 768px) {
.nav-links, .nav-phone { display: none; }
.nav-links, nav > .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; }
@@ -495,116 +194,38 @@
}
/* ─── 2026 visual refresh ──────────────────────────────── */
:root {
--ink: #20302c;
--muted: #66736f;
--sage: #e9f1ec;
--sage-mid: #a8c7b6;
--cream: #fbf8f3;
--red-soft: #f9e9ec;
--line: rgba(32, 48, 44, .11);
--shadow: 0 18px 50px rgba(35, 55, 48, .10);
--radius: 20px;
}
:root { --ink: #20302c; --muted: #66736f; --sage: #e9f1ec; --sage-mid: #a8c7b6; --cream: #fbf8f3; --red-soft: #f9e9ec; --line: rgba(32, 48, 44, .11); --shadow: 0 18px 50px rgba(35, 55, 48, .10); --radius: 20px; }
body { color: var(--ink); background: var(--cream); }
section { padding: 96px 24px; scroll-margin-top: 82px; }
section.alt { background: #f3f6f3; }
.section-inner, nav, .hero-inner, .hero-cards { max-width: 1180px; }
.section-title {
font-family: 'DM Sans', sans-serif;
color: var(--ink);
font-size: clamp(2rem, 4vw, 3.15rem);
font-weight: 600;
line-height: 1.12;
letter-spacing: -.035em;
margin-bottom: 12px;
}
.section-title::before {
content: '';
display: block;
width: 42px;
height: 4px;
margin-bottom: 20px;
border-radius: 999px;
background: var(--red);
}
.section-title { font-family: 'DM Sans', sans-serif; color: var(--ink); font-size: clamp(2rem, 4vw, 3.15rem); font-weight: 600; line-height: 1.12; letter-spacing: -.035em; margin-bottom: 12px; }
.section-title::before { content: ''; display: block; width: 42px; height: 4px; margin-bottom: 20px; border-radius: 999px; background: var(--red); }
.section-sub { color: var(--muted); font-size: 17px; margin-bottom: 44px; }
header {
background: rgba(255, 255, 255, .94);
border-bottom: 1px solid rgba(32, 48, 44, .08);
box-shadow: 0 8px 30px rgba(35, 55, 48, .06);
backdrop-filter: blur(16px);
}
header { background: rgba(255, 255, 255, .94); border-bottom: 1px solid rgba(32, 48, 44, .08); box-shadow: 0 8px 30px rgba(35, 55, 48, .06); backdrop-filter: blur(16px); }
nav { height: 82px; }
.nav-logo img { height: 48px; }
.nav-logo img { height: 64px; }
.nav-links { gap: 30px; }
.nav-links a { color: #41504c; font-size: 15px; font-weight: 600; }
.nav-phone {
border-radius: 999px;
padding: 11px 18px;
box-shadow: 0 8px 22px rgba(200, 16, 46, .20);
}
.nav-phone { border-radius: 999px; padding: 11px 18px; box-shadow: 0 8px 22px rgba(200, 16, 46, .20); }
.nav-phone svg, .btn svg { width: 19px; height: 19px; fill: none; stroke: currentColor; stroke-width: 2; }
.font-toggle-wrap button { border-color: var(--line); border-radius: 999px; }
.font-toggle-wrap button.active { background: var(--red-soft); }
#hero {
padding: 30px 24px 0;
min-height: auto;
background:
#hero { padding: 30px 24px 0; min-height: auto; background:
radial-gradient(circle at 8% 10%, rgba(168, 199, 182, .22), transparent 28%),
var(--cream);
}
var(--cream); }
.hero-watermark { display: none; }
.hero-inner {
position: relative;
display: block;
min-height: 590px;
overflow: hidden;
border-radius: 30px;
background: #f4f1eb;
box-shadow: var(--shadow);
}
.hero-inner::after {
content: '';
position: absolute;
inset: 0;
z-index: 1;
pointer-events: none;
background: linear-gradient(90deg, rgba(251,248,243,.99) 0%, rgba(251,248,243,.96) 33%, rgba(251,248,243,.58) 51%, rgba(251,248,243,0) 72%);
}
.hero-inner { position: relative; display: block; min-height: 590px; overflow: hidden; border-radius: 30px; background: #f4f1eb; box-shadow: var(--shadow); }
.hero-inner::after { content: ''; position: absolute; inset: 0; z-index: 1; pointer-events: none; background: linear-gradient(90deg, rgba(251,248,243,.99) 0%, rgba(251,248,243,.96) 33%, rgba(251,248,243,.58) 51%, rgba(251,248,243,0) 72%); }
.hero-visual { position: absolute; inset: 0; margin: 0; }
.hero-visual picture { display: block; width: 100%; height: 100%; }
.hero-visual img { width: 100%; height: 100%; object-fit: cover; object-position: center; }
.hero-text {
position: relative;
z-index: 2;
width: 55%;
padding: 84px 0 72px 64px;
animation: fadeUp .7s ease both;
}
.eyebrow {
display: inline-flex;
align-items: center;
gap: 9px;
color: var(--red);
font-size: 13px;
font-weight: 700;
letter-spacing: .11em;
text-transform: uppercase;
margin-bottom: 20px;
}
.hero-text { position: relative; z-index: 2; width: 55%; padding: 84px 0 72px 64px; animation: fadeUp .7s ease both; }
.eyebrow { display: inline-flex; align-items: center; gap: 9px; color: var(--red); font-size: 13px; font-weight: 700; letter-spacing: .11em; text-transform: uppercase; margin-bottom: 20px; }
.eyebrow::before { content: ''; width: 26px; height: 2px; background: currentColor; }
.hero-text h1 {
max-width: 620px;
font-family: 'DM Sans', sans-serif;
font-size: clamp(2.8rem, 5.3vw, 4.35rem);
font-weight: 600;
line-height: 1.02;
letter-spacing: -.055em;
color: var(--ink);
margin-bottom: 24px;
}
.hero-text h1 { max-width: 620px; font-family: 'DM Sans', sans-serif; font-size: clamp(2.8rem, 5.3vw, 4.35rem); font-weight: 600; line-height: 1.02; letter-spacing: -.055em; color: var(--ink); margin-bottom: 24px; }
.hero-text h1 span { color: var(--red); }
.hero-text p { max-width: 510px; color: #52615c; font-size: 18px; line-height: 1.65; margin-bottom: 32px; }
.btn { min-height: 52px; padding: 13px 22px; border-radius: 999px; }
@@ -613,27 +234,10 @@
.hero-trust { display: flex; gap: 22px; flex-wrap: wrap; margin-top: 30px; color: #4f605a; font-size: 14px; font-weight: 600; }
.hero-trust span { display: inline-flex; align-items: center; gap: 7px; }
.hero-trust svg { width: 18px; height: 18px; color: #668f79; fill: none; stroke: currentColor; stroke-width: 2; }
.hero-cards {
position: relative;
z-index: 3;
margin: -34px auto 0;
padding: 0 26px;
gap: 0;
border-radius: 20px;
background: #fff;
box-shadow: 0 16px 46px rgba(35,55,48,.12);
}
.hero-cards { position: relative; z-index: 3; margin: -34px auto 0; padding: 0 26px; gap: 0; border-radius: 20px; background: #fff; box-shadow: 0 16px 46px rgba(35,55,48,.12); }
.hero-card { min-width: 0; padding: 24px 22px; background: #fff; border-radius: 0; border-right: 1px solid var(--line); }
.hero-card:last-child { border-right: 0; }
.hero-card-icon {
display: grid;
place-items: center;
width: 42px;
height: 42px;
border-radius: 13px;
background: var(--sage);
color: #527b65;
}
.hero-card-icon { display: grid; place-items: center; width: 42px; height: 42px; border-radius: 13px; background: var(--sage); color: #527b65; }
.hero-card-icon svg, .leistung-icon svg, .kontakt-icon svg { width: 23px; height: 23px; fill: none; stroke: currentColor; stroke-width: 1.8; stroke-linecap: round; stroke-linejoin: round; }
.hero-card-label { color: #87918e; font-size: 12px; letter-spacing: .08em; }
.hero-card-value { color: var(--ink); font-size: 15px; line-height: 1.45; overflow-wrap: anywhere; }
@@ -641,13 +245,7 @@
#oeffnungszeiten { padding-top: 110px; }
.hours-layout { display: grid; grid-template-columns: minmax(0, 1.25fr) minmax(280px, .75fr); gap: 28px; align-items: stretch; }
.hours-grid { max-width: none; gap: 12px; }
.hour-card {
border: 1px solid var(--line);
border-left: 0;
border-radius: 14px;
box-shadow: none;
padding: 17px 20px;
}
.hour-card { border: 1px solid var(--line); border-left: 0; border-radius: 14px; box-shadow: none; padding: 17px 20px; }
.hour-card:hover { transform: translateY(-2px); box-shadow: 0 10px 26px rgba(35,55,48,.08); }
.hour-time { color: var(--red); }
.hours-note { padding: 34px; border-radius: var(--radius); background: var(--ink); color: #fff; }
@@ -662,15 +260,7 @@
.closure-dates { font-family: 'DM Sans', sans-serif; color: var(--red); }
.leistungen-grid { gap: 18px; }
.leistung-card {
position: relative;
overflow: hidden;
min-height: 225px;
padding: 30px;
border: 1px solid var(--line);
border-radius: var(--radius);
box-shadow: none;
}
.leistung-card { position: relative; overflow: hidden; min-height: 225px; padding: 30px; border: 1px solid var(--line); border-radius: var(--radius); box-shadow: none; }
.leistung-card::after { content: ''; position: absolute; right: -34px; bottom: -48px; width: 110px; height: 110px; border-radius: 50%; background: var(--sage); transition: transform .3s ease; }
.leistung-card:hover { transform: translateY(-5px); box-shadow: 0 18px 38px rgba(35,55,48,.10); }
.leistung-card:hover::after { transform: scale(1.22); }
@@ -696,7 +286,7 @@
.map-wrap iframe { height: 100%; min-height: 410px; }
footer { padding: 50px 24px; background: #21332e; color: #bfd0c8; }
footer img { height: 44px; filter: brightness(0) invert(1); opacity: .88; }
footer img { display: block; box-sizing: content-box; height: 60px; width: auto; padding: 12px 18px; border-radius: 12px; background: #fff; filter: none; opacity: 1; }
footer a { color: #eef4f1; }
@media (max-width: 980px) {
@@ -727,7 +317,7 @@
}
@media (max-width: 540px) {
section { padding: 64px 16px; }
.nav-logo img { height: 42px; }
.nav-logo img { height: 56px; }
.hero-text { padding: 36px 22px 30px; }
.hero-cta { display: grid; }
.btn { justify-content: center; }
@@ -746,9 +336,28 @@
html { scroll-behavior: auto; }
*, *::before, *::after { animation-duration: .01ms !important; animation-iteration-count: 1 !important; transition-duration: .01ms !important; }
}
/* Keyboard navigation and patient information */
:focus-visible { outline: 3px solid #C8102E; outline-offset: 4px; }
.skip-link { position: fixed; top: 8px; left: 16px; z-index: 200; padding: 12px 18px; background: #fff; color: #20302c; border-radius: 8px; transform: translateY(-160%); }
.skip-link:focus { transform: translateY(0); }
.hamburger { min-width: 44px; min-height: 44px; align-items: center; justify-content: center; }
.font-toggle-wrap button { min-width: 44px; min-height: 44px; }
.hero-card-value a { text-decoration: none; }
.hero-card-value a:hover { color: var(--red); }
.first-visit { display: grid; grid-template-columns: 1.1fr 1fr; align-items: center; gap: 48px; }
.first-visit figure { margin: 0; }
.first-visit img { width: 100%; height: auto; border-radius: var(--radius); }
@media (max-width: 768px) {
.first-visit { grid-template-columns: 1fr; gap: 24px; }
}
.first-visit p { margin-bottom: 16px; }
.first-visit a { text-decoration: underline; text-underline-offset: 3px; }
.first-visit a[href^="tel:"], .first-visit a[href^="mailto:"] { text-decoration: none; }
</style>
</head>
<body>
<a class="skip-link" href="#main-content">Zum Inhalt springen</a>
<!-- ═══════════════════════════════════════════════════════════
SCHLIESSZEITEN — edit only this array to manage holidays
@@ -756,7 +365,8 @@
<script>
const SCHLIESSZEITEN = [
{
dates: "13.7. – 31.7.",
start: "2026-07-13",
end: "2026-07-31",
reason: "Urlaub",
deputy: "Dr. Monika Bauer",
deputyAddr: "1160 Wien, Gablenzgasse 118/11/5",
@@ -765,7 +375,8 @@ const SCHLIESSZEITEN = [
},
// Add more closures here:
// {
// dates: "DD.MM. – DD.MM.",
// start: "2027-12-28", // YYYY-MM-DD, including the year
// end: "2028-01-03",
// reason: "Urlaub",
// deputy: "Dr. Vorname Nachname",
// deputyAddr: "1160 Wien, Musterstraße 1",
@@ -779,7 +390,7 @@ const SCHLIESSZEITEN = [
<header>
<nav>
<a class="nav-logo" href="#hero">
<img src="/logo.png" alt="meineOrdi Logo" />
<img src="/meineordi.png" alt="meineOrdi Logo" />
</a>
<ul class="nav-links">
<li><a href="#oeffnungszeiten">Öffnungszeiten</a></li>
@@ -788,14 +399,14 @@ const SCHLIESSZEITEN = [
<li><a href="#kontakt">Kontakt</a></li>
</ul>
<div class="font-toggle-wrap" aria-label="Schriftgröße">
<button id="font-normal" title="Normale Schriftgröße">A</button>
<button id="font-large" title="Große Schriftgröße">A+</button>
<button id="font-normal" title="Normale Schriftgröße" aria-pressed="false">A</button>
<button id="font-large" title="Große Schriftgröße" aria-pressed="false">A+</button>
</div>
<a class="nav-phone" href="tel:+4314931773">
<svg viewBox="0 0 24 24" aria-hidden="true"><path d="M22 16.92v3a2 2 0 0 1-2.18 2 19.8 19.8 0 0 1-8.63-3.07 19.5 19.5 0 0 1-6-6A19.8 19.8 0 0 1 2.12 4.18 2 2 0 0 1 4.11 2h3a2 2 0 0 1 2 1.72c.12.9.33 1.78.62 2.63a2 2 0 0 1-.45 2.11L8 9.73a16 16 0 0 0 6 6l1.27-1.27a2 2 0 0 1 2.11-.45c.85.29 1.73.5 2.63.62A2 2 0 0 1 22 16.92z"/></svg>
+43 1 493 17 73
</a>
<button class="hamburger" id="hamburger" aria-label="Menü öffnen">
<button class="hamburger" id="hamburger" aria-label="Menü öffnen" aria-expanded="false" aria-controls="mobile-menu">
<span></span><span></span><span></span>
</button>
</nav>
@@ -806,17 +417,21 @@ const SCHLIESSZEITEN = [
<a href="#kontakt">Kontakt</a>
<a class="nav-phone" href="tel:+4314931773"><svg viewBox="0 0 24 24" aria-hidden="true"><path d="M22 16.92v3a2 2 0 0 1-2.18 2 19.8 19.8 0 0 1-8.63-3.07 19.5 19.5 0 0 1-6-6A19.8 19.8 0 0 1 2.12 4.18 2 2 0 0 1 4.11 2h3a2 2 0 0 1 2 1.72c.12.9.33 1.78.62 2.63a2 2 0 0 1-.45 2.11L8 9.73a16 16 0 0 0 6 6l1.27-1.27a2 2 0 0 1 2.11-.45c.85.29 1.73.5 2.63.62A2 2 0 0 1 22 16.92z"/></svg> +43 1 493 17 73</a>
<div class="font-toggle-wrap" style="justify-content:center;">
<button id="font-normal-mobile" title="Normale Schriftgröße">A</button>
<button id="font-large-mobile" title="Große Schriftgröße">A+</button>
<button id="font-normal-mobile" title="Normale Schriftgröße" aria-pressed="false">A</button>
<button id="font-large-mobile" title="Große Schriftgröße" aria-pressed="false">A+</button>
</div>
</div>
</header>
<main id="main-content" tabindex="-1">
<!-- ─── Hero ─────────────────────────────────────────────── -->
<section id="hero">
<div class="hero-inner">
<figure class="hero-visual">
<img src="/praxis-hero.png" alt="Stethoskop in einer hellen, freundlichen Ordination" width="1944" height="1024" fetchpriority="high" />
<picture>
<source type="image/webp" srcset="/praxis-hero-960.webp 960w, /praxis-hero.webp 1916w" sizes="(max-width: 768px) calc(100vw - 32px), (max-width: 1228px) calc(100vw - 48px), 1180px" />
<img src="/praxis-hero.png" alt="Stethoskop in einer hellen, freundlichen Ordination" width="1916" height="821" fetchpriority="high" />
</picture>
</figure>
<div class="hero-text">
<div class="eyebrow">Allgemeinmedizin in 1160 Wien</div>
@@ -838,21 +453,21 @@ const SCHLIESSZEITEN = [
<div class="hero-card-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><path d="M20 10c0 5-8 12-8 12S4 15 4 10a8 8 0 1 1 16 0Z"/><circle cx="12" cy="10" r="2.5"/></svg></div>
<div>
<div class="hero-card-label">Adresse</div>
<div class="hero-card-value">Pfenninggeldgasse 1B/3<br>A-1160 Wien</div>
<div class="hero-card-value"><a href="https://www.google.com/maps/dir/?api=1&amp;destination=Pfenninggeldgasse+1B%2F3%2C+1160+Wien" aria-label="Route zur Ordination planen">Pfenninggeldgasse 1B/3<br>A-1160 Wien</a></div>
</div>
</div>
<div class="hero-card">
<div class="hero-card-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><path d="M22 16.92v3a2 2 0 0 1-2.18 2 19.8 19.8 0 0 1-8.63-3.07 19.5 19.5 0 0 1-6-6A19.8 19.8 0 0 1 2.12 4.18 2 2 0 0 1 4.11 2h3a2 2 0 0 1 2 1.72c.12.9.33 1.78.62 2.63a2 2 0 0 1-.45 2.11L8 9.73a16 16 0 0 0 6 6l1.27-1.27a2 2 0 0 1 2.11-.45c.85.29 1.73.5 2.63.62A2 2 0 0 1 22 16.92z"/></svg></div>
<div>
<div class="hero-card-label">Telefon</div>
<div class="hero-card-value">+43 / 1 / 493 17 73</div>
<div class="hero-card-value"><a href="tel:+4314931773">+43 / 1 / 493 17 73</a></div>
</div>
</div>
<div class="hero-card">
<div class="hero-card-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><rect x="3" y="5" width="18" height="14" rx="2"/><path d="m3 7 9 6 9-6"/></svg></div>
<div>
<div class="hero-card-label">E-Mail</div>
<div class="hero-card-value">info@meineordi.at</div>
<div class="hero-card-value"><a href="mailto:info@meineordi.at">info@meineordi.at</a></div>
</div>
</div>
<div class="hero-card">
@@ -907,6 +522,20 @@ const SCHLIESSZEITEN = [
</div>
</section>
<section id="erster-besuch">
<div class="section-inner first-visit">
<div>
<h2 class="section-title">Ihr erster Besuch</h2>
<p>Bitte vereinbaren Sie vor Ihrem Besuch telefonisch einen Termin unter <a href="tel:+4314931773">+43 1 493 17 73</a>.</p>
<p>Bei der Terminvereinbarung können Sie auch Fragen zu Kassenleistungen, zur Aufnahme neuer Patientinnen und Patienten, zu benötigten Unterlagen und zum Zugang zur Ordination klären.</p>
<p>Sie finden uns in der Pfenninggeldgasse 1B/3, 1160 Wien. <a href="https://www.google.com/maps/dir/?api=1&amp;destination=Pfenninggeldgasse+1B%2F3%2C+1160+Wien">Anreise planen</a></p>
</div>
<figure>
<img src="/erster-besuch-abstrakt.webp" alt="" width="1200" height="800" loading="lazy" decoding="async" />
</figure>
</div>
</section>
<!-- ─── Schließzeiten ─────────────────────────────────────── -->
<section id="schliesszeiten">
<div class="section-inner">
@@ -1038,9 +667,10 @@ const SCHLIESSZEITEN = [
</section>
<!-- ─── Footer ────────────────────────────────────────────── -->
</main>
<footer>
<div class="footer-inner">
<img src="/logo.png" alt="meineOrdi" />
<img src="/meineordi.png" alt="meineOrdi" />
<p>
&copy; <span id="footer-year"></span> Dr. med. Carina Kautsch &nbsp;·&nbsp;
Ärztin für Allgemeinmedizin &nbsp;·&nbsp; 1160 Wien
@@ -1056,20 +686,71 @@ const SCHLIESSZEITEN = [
// Hamburger menu
const hamburger = document.getElementById('hamburger');
const mobileMenu = document.getElementById('mobile-menu');
hamburger.addEventListener('click', () => {
hamburger.classList.toggle('open');
mobileMenu.classList.toggle('open');
function setMenuOpen(open) {
hamburger.classList.toggle('open', open);
mobileMenu.classList.toggle('open', open);
hamburger.setAttribute('aria-expanded', String(open));
hamburger.setAttribute('aria-label', open ? 'Menü schließen' : 'Menü öffnen');
}
hamburger.addEventListener('click', () => setMenuOpen(hamburger.getAttribute('aria-expanded') !== 'true'));
document.addEventListener('keydown', event => {
if (event.key === 'Escape' && hamburger.getAttribute('aria-expanded') === 'true') {
setMenuOpen(false);
hamburger.focus();
}
});
window.matchMedia('(min-width: 769px)').addEventListener('change', event => {
if (event.matches) setMenuOpen(false);
});
mobileMenu.querySelectorAll('a').forEach(a => {
a.addEventListener('click', () => {
hamburger.classList.remove('open');
mobileMenu.classList.remove('open');
setMenuOpen(false);
const target = document.getElementById(a.hash.slice(1));
if (target && a.pathname === window.location.pathname) {
target.setAttribute('tabindex', '-1');
target.focus({ preventScroll: true });
}
});
});
// Footer year
document.getElementById('footer-year').textContent = new Date().getFullYear();
function viennaDate(now = new Date()) {
const parts = new Intl.DateTimeFormat('en-GB', {
timeZone: 'Europe/Vienna', year: 'numeric', month: '2-digit', day: '2-digit'
}).formatToParts(now);
const value = type => parts.find(part => part.type === type).value;
return `${value('year')}-${value('month')}-${value('day')}`;
}
function isClosureDay(today, closures = SCHLIESSZEITEN) {
return closures.some(c => c.start <= today && today <= c.end);
}
// Austrian national holidays; movable dates are relative to Easter Sunday.
// Reference: https://www.wien.gv.at/inhalt/feiertage
function isPublicHoliday(today) {
if (['01-01', '01-06', '05-01', '08-15', '10-26', '11-01', '12-08', '12-25', '12-26'].includes(today.slice(5))) return true;
const year = Number(today.slice(0, 4));
const a = year % 19, b = Math.floor(year / 100), c = year % 100;
const d = Math.floor(b / 4), e = b % 4;
const f = Math.floor((b + 8) / 25), g = Math.floor((b - f + 1) / 3);
const h = (19 * a + b - d - g + 15) % 30;
const i = Math.floor(c / 4), k = c % 4;
const l = (32 + 2 * e + 2 * i - h - k) % 7;
const m = Math.floor((a + 11 * h + 22 * l) / 451);
const month = Math.floor((h + l - 7 * m + 114) / 31);
const day = (h + l - 7 * m + 114) % 31 + 1;
return [1, 39, 50, 60].some(offset =>
new Date(Date.UTC(year, month - 1, day + offset)).toISOString().slice(0, 10) === today);
}
function formatClosureDates(closure) {
const format = iso => iso.split('-').reverse().join('.');
return `${format(closure.start)} – ${format(closure.end)}`;
}
// Today's hours in hero card
(function() {
const hours = {
@@ -1080,32 +761,15 @@ const SCHLIESSZEITEN = [
5: '09:00 – 12:00',
};
// Check if today falls within any defined closure period
function isClosureDay() {
const today = new Date();
today.setHours(0, 0, 0, 0);
for (const c of SCHLIESSZEITEN) {
// Parse date strings like "30.3." from "30.3. – 3.4."
const parts = c.dates.split('–');
if (parts.length !== 2) continue;
function parseDate(s) {
const p = s.trim().replace(/\.$/, '').split('.');
const d = parseInt(p[0]), m = parseInt(p[1]) - 1;
let start = new Date(today.getFullYear(), m, d);
return start;
}
const start = parseDate(parts[0]);
const end = parseDate(parts[1]);
// Handle year wrap (e.g. 28.12. – 3.1.)
if (end < start) end.setFullYear(end.getFullYear() + 1);
if (today >= start && today <= end) return true;
}
return false;
function updateTodaysHours() {
const today = viennaDate();
const day = new Date(`${today}T12:00:00Z`).getUTCDay();
const el = document.getElementById('todays-hours');
el.textContent = isClosureDay(today) ? 'Geschlossen – Abwesenheit'
: isPublicHoliday(today) ? 'Geschlossen – Feiertag' : (hours[day] || 'Geschlossen');
}
const day = new Date().getDay(); // 0=Sun, 1=Mon, …
const el = document.getElementById('todays-hours');
el.textContent = isClosureDay() ? 'Geschlossen' : (hours[day] || 'Geschlossen');
updateTodaysHours();
setInterval(updateTodaysHours, 60000);
})();
// Render closure cards
@@ -1117,7 +781,7 @@ const SCHLIESSZEITEN = [
}
const cards = SCHLIESSZEITEN.map(c => `
<div class="closure-card">
<div class="closure-dates">${c.dates}</div>
<div class="closure-dates">${formatClosureDates(c)}</div>
<div class="closure-reason">${c.reason}</div>
<div class="closure-deputy-label">Vertretung</div>
<div class="closure-deputy-name">${c.deputy}</div>
@@ -1146,11 +810,16 @@ const SCHLIESSZEITEN = [
btnLrg.classList.toggle('active', large);
btnNormM.classList.toggle('active', !large);
btnLrgM.classList.toggle('active', large);
localStorage.setItem('fontSize', large ? 'large' : 'normal');
[btnNorm, btnNormM].forEach(button => button.setAttribute('aria-pressed', String(!large)));
[btnLrg, btnLrgM].forEach(button => button.setAttribute('aria-pressed', String(large)));
try { localStorage.setItem('fontSize', large ? 'large' : 'normal'); } catch {}
}
// Apply saved preference
setSize(localStorage.getItem('fontSize') === 'large');
let savedLarge = false;
try { savedLarge = localStorage.getItem('fontSize') === 'large'; } catch {}
setSize(savedLarge);
btnNorm.addEventListener('click', () => setSize(false));
btnLrg.addEventListener('click', () => setSize(true));
BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 123 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 61 KiB

+70
View File
@@ -0,0 +1,70 @@
const { test } = require('node:test');
const assert = require('node:assert/strict');
const fs = require('node:fs');
const vm = require('node:vm');
const html = fs.readFileSync('index.html', 'utf8');
const calendar = html.slice(html.indexOf(' function viennaDate('), html.indexOf(" // Today's hours in hero card"));
const context = vm.createContext({ Intl, Date });
vm.runInContext(calendar, context);
test('closures include boundaries and cross years without repeating annually', () => {
const closures = [{ start: '2026-12-28', end: '2027-01-03' }];
for (const date of ['2026-12-28', '2026-12-31', '2027-01-01', '2027-01-03']) {
assert.equal(context.isClosureDay(date, closures), true, date);
}
for (const date of ['2026-12-27', '2027-01-04', '2027-12-28']) {
assert.equal(context.isClosureDay(date, closures), false, date);
}
assert.equal(context.isClosureDay('2026-10-14', []), false);
});
test('Vienna date remains correct around midnight and daylight saving time', () => {
assert.equal(context.viennaDate(new Date('2026-10-13T22:30:00Z')), '2026-10-14');
assert.equal(context.viennaDate(new Date('2026-12-31T23:30:00Z')), '2027-01-01');
assert.equal(context.viennaDate(new Date('2026-03-29T22:30:00Z')), '2026-03-30');
});
test('national holidays include fixed and movable holidays in 2026 and 2027', () => {
for (const date of ['2026-01-01', '2026-01-06', '2026-04-06', '2026-05-01', '2026-05-14', '2026-05-25', '2026-06-04', '2026-08-15', '2026-10-26', '2026-11-01', '2026-12-08', '2026-12-25', '2026-12-26', '2027-03-29', '2027-05-06', '2027-05-17', '2027-05-27']) {
assert.equal(context.isPublicHoliday(date), true, date);
}
for (const date of ['2026-10-14', '2026-04-03', '2026-11-15', '2026-12-24', '2027-04-06']) {
assert.equal(context.isPublicHoliday(date), false, date);
}
});
for (const file of ['index.html', 'impressum.html']) {
test(`${file}: scripts work when browser storage is blocked; menu and font states stay accessible`, () => {
const source = fs.readFileSync(file, 'utf8');
const elements = new Map();
const getElement = id => {
if (!elements.has(id)) elements.set(id, {
attrs: { 'aria-expanded': 'false' }, listeners: {}, classList: { toggle() {}, remove() {} },
setAttribute(key, value) { this.attrs[key] = value; },
getAttribute(key) { return this.attrs[key]; },
addEventListener(event, callback) { this.listeners[event] = callback; },
querySelectorAll() { return []; }, focus() { this.focused = true; }
});
return elements.get(id);
};
const document = { body: getElement('body'), getElementById: getElement, addEventListener() {} };
const sandbox = vm.createContext({ document, Intl, Date, setInterval() {},
localStorage: { getItem() { throw Error('blocked'); }, setItem() { throw Error('blocked'); } },
window: { matchMedia() { return { addEventListener() {} }; } }
});
const scripts = [...source.matchAll(/<script>([\s\S]*?)<\/script>/g)].map(match => match[1]);
for (const script of scripts) {
new vm.Script(script);
if (!script.includes('var _paq')) vm.runInContext(script, sandbox);
}
const menu = getElement('hamburger');
menu.listeners.click();
assert.equal(menu.attrs['aria-expanded'], 'true');
assert.equal(menu.attrs['aria-label'], 'Menü schließen');
menu.listeners.click();
assert.equal(menu.attrs['aria-expanded'], 'false');
getElement('font-large').listeners.click();
assert.equal(getElement('font-large-mobile').attrs['aria-pressed'], 'true');
assert.equal(getElement('font-normal').attrs['aria-pressed'], 'false');
});
}