README hinzugefuegt, Lint-Fehler behoben, Code formatiert

This commit is contained in:
2026-05-10 02:15:40 +02:00
parent 5d1a048624
commit d25525946d
13 changed files with 1536 additions and 592 deletions

2
.gitignore vendored
View File

@@ -1,2 +1,4 @@
*.ps1
*.py
/node_modules/
package-lock.json

1
.htmlhintrc Normal file
View File

@@ -0,0 +1 @@
{"attr-value-not-empty":false,"tag-pair":true,"tagname-lowercase":true,"attr-lowercase":true,"doctype-first":true,"id-unique":true,"src-not-empty":false,"title-require":true,"alt-require":true}

1
.husky/pre-commit Normal file
View File

@@ -0,0 +1 @@
npx lint-staged

3
.prettierignore Normal file
View File

@@ -0,0 +1,3 @@
node_modules
*.min.js
*.min.css

1
.prettierrc Normal file
View File

@@ -0,0 +1 @@
{"semi":true,"singleQuote":false,"tabWidth":2,"trailingComma":"all","printWidth":100,"bracketSpacing":true,"arrowParens":"always","endOfLine":"lf","htmlWhitespaceSensitivity":"ignore"}

11
.stylelintrc.json Normal file
View File

@@ -0,0 +1,11 @@
{
"extends": ["stylelint-config-standard"],
"plugins": ["stylelint-prettier"],
"rules": {
"prettier/prettier": true,
"selector-class-pattern": null,
"selector-id-pattern": null,
"no-descending-specificity": null
},
"ignoreFiles": ["node_modules/**", "**/*.min.css"]
}

175
README.md Normal file
View File

@@ -0,0 +1,175 @@
# Landingpage Haus Schleusingen
Statische Landingpage für **Haus Schleusingen**.
Das Projekt basiert auf reinem HTML, CSS und JavaScript und wird über einen Nginx-Container ausgeliefert.
---
## Inhaltsübersicht
```
├── bilder/ # Bildressourcen
├── css/
│ └── haus-schleusingen.css # Hauptstylesheet
├── fonts/
│ └── fonts.css # Schriftart-Einbindungen
├── js/
│ ├── haus-schleusingen.js # Haupt-JavaScript
│ └── masonry.pkgd.min.js # Masonry-Layout-Bibliothek
├── haus-schleusingen.html # Einstiegsseite
├── nginx.conf # Nginx-Konfiguration
├── Dockerfile # Docker-Image (nginx:alpine)
├── eslint.config.js # ESLint-Konfiguration
├── .stylelintrc.json # Stylelint-Konfiguration
├── .htmlhintrc # HTMLHint-Konfiguration
├── .prettierrc # Prettier-Konfiguration
├── .husky/pre-commit # Husky Git-Hook (lint-staged)
└── package.json # Projekt-Metadaten & Skripte
```
---
## Voraussetzungen
| Werkzeug | Version |
| -------- | --------------- |
| Node.js | ≥ 18 |
| npm | ≥ 9 |
| Docker | optional (≥ 20) |
---
## Installation
```bash
# Repository klonen
git clone https://git.home.kies-media.de/greggy/landingpage-haus-schleusingen.git
cd landingpage-haus-schleusingen
# Abhängigkeiten installieren
npm install
```
---
## Entwicklung
### Lokaler Dateiserver
Für die Entwicklung empfiehlt sich ein lokaler Server, z. B.:
```bash
npx serve .
```
Oder mit der in VS Code integrierten _Live Server_-Erweiterung.
---
## Deployment mit Docker
Das Projekt enthält ein vorkonfiguriertes Nginx-Image.
```bash
# Image bauen
docker build -t landingpage-haus-schleusingen .
# Container starten (Website-Dateien per Volume einbinden)
docker run -d \
-p 8080:80 \
-v $(pwd):/usr/share/nginx/html:ro \
landingpage-haus-schleusingen
```
Die Seite ist danach unter **http://localhost:8080** erreichbar.
---
## Code-Qualität & Linting
Das Projekt nutzt eine Kombination aus mehreren Linting- und Formatierungswerkzeugen, um eine einheitliche Code-Qualität sicherzustellen:
| Werkzeug | Zweck | Konfigurationsdatei |
| --------------- | ---------------------------------- | ------------------- |
| **ESLint** | JavaScript-Linting | `eslint.config.js` |
| **Stylelint** | CSS-Linting | `.stylelintrc.json` |
| **HTMLHint** | HTML-Linting | `.htmlhintrc` |
| **Prettier** | Code-Formatierung | `.prettierrc` |
| **Husky** | Git Hooks (Pre-Commit) | `.husky/pre-commit` |
| **lint-staged** | Linting nur für gesteuerte Dateien | `package.json` |
### Befehle
#### Alle Linter auf einmal ausführen
```bash
npm run lint
```
Dadurch werden nacheinander `lint:html`, `lint:css` und `lint:js` ausgeführt.
#### HTML linten
```bash
npm run lint:html
```
Prüft alle `.html`-Dateien mit **HTMLHint**.
Regeln (`.htmlhintrc`):
- Tag-Paarung (`tag-pair`)
- Kleinschreibung von Tags & Attributen (`tagname-lowercase`, `attr-lowercase`)
- Doctype zuerst (`doctype-first`)
- Eindeutige IDs (`id-unique`)
- `alt`-Attribut bei Bildern (`alt-require`)
- Titel erforderlich (`title-require`)
#### CSS linten
```bash
npm run lint:css
```
Prüft alle CSS-Dateien in `css/` und `fonts/` mit **Stylelint** (basiert auf `stylelint-config-standard`).
#### JavaScript linten
```bash
npm run lint:js
```
Prüft alle `.js`-Dateien in `js/` mit **ESLint** (minimierte Dateien werden ignoriert).
Regeln (`eslint.config.js`):
- `no-unused-vars` → Warnung
- `no-undef` → Warnung
- Prettier-Integration (`prettier/prettier` → Fehler)
#### Code formatieren
```bash
npm run format
```
Formatiert alle `html`, `css`, `js`, `json` und `md`-Dateien mit **Prettier** (in-place).
#### Formatierung prüfen (ohne Änderungen)
```bash
npm run format:check
```
Prüft, ob alle Dateien den Prettier-Vorgaben entsprechen, ohne sie zu verändern.
#### Husky Pre-Commit Hook
Bei jedem `git commit` werden automatisch **lint-staged**-Prüfungen ausgeführt:
| Dateityp | Aktionen |
| -------------- | ------------------------------ |
| `*.html` | HTMLHint + Prettier |
| `*.css` | Stylelint (`--fix`) + Prettier |
| `*.js` | ESLint (`--fix`) + Prettier |
| `*.json, *.md` | Prettier |

File diff suppressed because it is too large Load Diff

31
eslint.config.js Normal file
View File

@@ -0,0 +1,31 @@
const globals = require("globals");
const js = require("@eslint/js");
const prettierPlugin = require("eslint-plugin-prettier");
const prettierConfig = require("eslint-config-prettier");
module.exports = [
js.configs.recommended,
prettierConfig,
{
files: ["**/*.js"],
languageOptions: {
ecmaVersion: "latest",
sourceType: "script",
globals: {
...globals.browser,
...globals.jquery,
},
},
plugins: {
prettier: prettierPlugin,
},
rules: {
"prettier/prettier": "error",
"no-unused-vars": "warn",
"no-undef": "warn",
},
},
{
ignores: ["node_modules/**", "**/*.min.js"],
},
];

View File

@@ -1,47 +1,47 @@
@font-face {
font-family: 'Cormorant Garamond';
font-family: "Cormorant Garamond";
font-style: normal;
font-weight: 300;
font-display: swap;
src: url('CormorantGaramond-Light.ttf') format('truetype');
src: url("CormorantGaramond-Light.ttf") format("truetype");
}
@font-face {
font-family: 'Cormorant Garamond';
font-family: "Cormorant Garamond";
font-style: normal;
font-weight: 400;
font-display: swap;
src: url('CormorantGaramond-Regular.ttf') format('truetype');
src: url("CormorantGaramond-Regular.ttf") format("truetype");
}
@font-face {
font-family: 'Cormorant Garamond';
font-family: "Cormorant Garamond";
font-style: normal;
font-weight: 600;
font-display: swap;
src: url('CormorantGaramond-SemiBold.ttf') format('truetype');
src: url("CormorantGaramond-SemiBold.ttf") format("truetype");
}
@font-face {
font-family: 'DM Sans';
font-family: "DM Sans";
font-style: normal;
font-weight: 300;
font-display: swap;
src: url('DMSans-Light.ttf') format('truetype');
src: url("DMSans-Light.ttf") format("truetype");
}
@font-face {
font-family: 'DM Sans';
font-family: "DM Sans";
font-style: normal;
font-weight: 400;
font-display: swap;
src: url('DMSans-Regular.ttf') format('truetype');
src: url("DMSans-Regular.ttf") format("truetype");
}
@font-face {
font-family: 'DM Sans';
font-family: "DM Sans";
font-style: normal;
font-weight: 500;
font-display: swap;
src: url('DMSans-Medium.ttf') format('truetype');
src: url("DMSans-Medium.ttf") format("truetype");
}

View File

@@ -1,20 +1,16 @@
<!DOCTYPE html>
<!doctype html>
<html lang="de">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Einfamilienhaus zur Miete - Schleusingen</title>
<link rel="stylesheet" href="fonts/fonts.css">
<script src="https://code.jquery.com/jquery-3.7.1.min.js"></script>
<!-- Masonry removed using CSS columns instead -->
<link rel="stylesheet" href="css/haus-schleusingen.css">
</head>
<body>
<nav id="navbar">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Einfamilienhaus zur Miete - Schleusingen</title>
<link rel="stylesheet" href="fonts/fonts.css" />
<script src="https://code.jquery.com/jquery-3.7.1.min.js"></script>
<!-- Masonry removed using CSS columns instead -->
<link rel="stylesheet" href="css/haus-schleusingen.css" />
</head>
<body>
<nav id="navbar">
<div class="nav-logo">Bahnhofstraße 10</div>
<ul class="nav-links">
<li><a href="#galerie">Galerie</a></li>
@@ -22,15 +18,30 @@
<li><a href="#miete">Miete</a></li>
<li><a href="#lage">Lage</a></li>
</ul>
<button class="nav-cta" onclick="$('html').animate({scrollTop: $('#kontakt').offset().top}, 700)">Jetzt anfragen</button>
</nav>
<button
class="nav-cta"
onclick="$('html').animate({ scrollTop: $('#kontakt').offset().top }, 700)"
>
Jetzt anfragen
</button>
</nav>
<section class="hero" id="hero">
<div class="hero-bg" id="heroBg" style="background-image:url(bilder/Außenansicht-2.png)"></div>
<section class="hero" id="hero">
<div
class="hero-bg"
id="heroBg"
style="background-image: url(bilder/Außenansicht-2.png)"
></div>
<div class="hero-overlay"></div>
<div class="hero-content" id="heroContent">
<div class="hero-tag">Zur Langzeitmiete · Ab sofort verfügbar</div>
<h1>Großzügiges<br><em>Einfamilienhaus</em><br>in Schleusingen</h1>
<h1>
Großzügiges
<br />
<em>Einfamilienhaus</em>
<br />
in Schleusingen
</h1>
<div class="hero-meta">
<span><strong>Schleusinger Bahnhofstraße 10</strong></span>
<span>227 m² Wohnfläche</span>
@@ -42,9 +53,9 @@
<span>Entdecken</span>
<div class="scroll-line"></div>
</div>
</section>
</section>
<div class="facts-strip">
<div class="facts-strip">
<div class="fact">
<div class="fact-val">227</div>
<div class="fact-label">m² Wohnfläche</div>
@@ -61,27 +72,43 @@
<div class="fact-val">1.300</div>
<div class="fact-label">€ Kaltmiete</div>
</div>
</div>
</div>
<section class="intro" id="intro">
<section class="intro" id="intro">
<div class="intro-text" data-animate>
<div class="section-eyebrow">Das Objekt</div>
<h2>Wohnen mit Charakter und viel Raum</h2>
<p>Vermietet wird ein vollständiges Einfamilienhaus in ruhiger Lage von Schleusingen. Das Haus verbindet historischen Charme mit modernem Wohnkomfort auf drei großzügigen Etagen.</p>
<p>Garage für zwei Fahrzeuge, großzügige Dachterrasse mit 35,8 m², vollausgestattete Küche, Vollbad sowie Abstell- und Nutzräume machen das Haus zu einem außergewöhnlichen Mietobjekt.</p>
<p>
Vermietet wird ein vollständiges Einfamilienhaus in ruhiger Lage von Schleusingen. Das
Haus verbindet historischen Charme mit modernem Wohnkomfort auf drei großzügigen Etagen.
</p>
<p>
Garage für zwei Fahrzeuge, großzügige Dachterrasse mit 35,8 m², vollausgestattete Küche,
Vollbad sowie Abstell- und Nutzräume machen das Haus zu einem außergewöhnlichen
Mietobjekt.
</p>
<div class="intro-stats">
<div><div class="istat-val">113 m²</div><div class="istat-label">Nutzfläche</div></div>
<div><div class="istat-val">35,8</div><div class="istat-label">Dachterrasse</div></div>
<div><div class="istat-val">2 Stpl.</div><div class="istat-label">Garage</div></div>
<div>
<div class="istat-val">113</div>
<div class="istat-label">Nutzfläche</div>
</div>
<div>
<div class="istat-val">35,8 m²</div>
<div class="istat-label">Dachterrasse</div>
</div>
<div>
<div class="istat-val">2 Stpl.</div>
<div class="istat-label">Garage</div>
</div>
</div>
</div>
<div class="intro-img" data-animate>
<img src="bilder/wohnzimmer2.png" />
<img src="bilder/wohnzimmer2.png" alt="Wohnzimmer" />
<div class="intro-img-badge">Wohnzimmer · 24,7 m²</div>
</div>
</section>
</section>
<section id="galerie" class="gallery-section">
<section id="galerie" class="gallery-section">
<div class="gallery-header">
<div>
<div class="section-eyebrow">Fotogalerie</div>
@@ -132,17 +159,23 @@
<span class="grid-item-label">Wohnbereich</span>
</div>
<div class="grid-item" data-img="bilder/WhatsApp Image 2026-03-30 at 07.50.42 (1).jpeg">
<img src="bilder/WhatsApp Image 2026-03-30 at 07.50.42 (1).jpeg" alt="Wohnbereich Detail 2" />
<img
src="bilder/WhatsApp Image 2026-03-30 at 07.50.42 (1).jpeg"
alt="Wohnbereich Detail 2"
/>
<span class="grid-item-label">Wohnbereich Detail</span>
</div>
<div class="grid-item" data-img="bilder/WhatsApp Image 2026-03-30 at 07.50.42 (2).jpeg">
<img src="bilder/WhatsApp Image 2026-03-30 at 07.50.42 (2).jpeg" alt="Wohnbereich Detail 3" />
<img
src="bilder/WhatsApp Image 2026-03-30 at 07.50.42 (2).jpeg"
alt="Wohnbereich Detail 3"
/>
<span class="grid-item-label">Hausansicht</span>
</div>
</div>
</section>
</section>
<section class="floors-section" id="grundriss">
<section class="floors-section" id="grundriss">
<div class="section-eyebrow">Raumaufteilung</div>
<h2>Großzügig auf allen Etagen</h2>
<div class="floor-accordion">
@@ -156,12 +189,30 @@
</div>
<div class="floor-body">
<div class="floor-rooms-grid">
<div class="room-chip">Flur <span class="room-chip-area">20,1 m²</span></div>
<div class="room-chip">WC <span class="room-chip-area">0,8 m²</span></div>
<div class="room-chip">Garage / Partykeller <span class="room-chip-area">42,6</span></div>
<div class="room-chip">Abstellraum 1 <span class="room-chip-area">9,9 m²</span></div>
<div class="room-chip">Abstellraum 2 <span class="room-chip-area">7,8 m²</span></div>
<div class="room-chip">Heizungskeller <span class="room-chip-area">18,3 m²</span></div>
<div class="room-chip">
Flur
<span class="room-chip-area">20,1</span>
</div>
<div class="room-chip">
WC
<span class="room-chip-area">0,8 m²</span>
</div>
<div class="room-chip">
Garage / Partykeller
<span class="room-chip-area">42,6 m²</span>
</div>
<div class="room-chip">
Abstellraum 1
<span class="room-chip-area">9,9 m²</span>
</div>
<div class="room-chip">
Abstellraum 2
<span class="room-chip-area">7,8 m²</span>
</div>
<div class="room-chip">
Heizungskeller
<span class="room-chip-area">18,3 m²</span>
</div>
</div>
</div>
</div>
@@ -175,12 +226,30 @@
</div>
<div class="floor-body">
<div class="floor-rooms-grid">
<div class="room-chip">Flur <span class="room-chip-area">20,1 m²</span></div>
<div class="room-chip">Wohnzimmer <span class="room-chip-area">24,7 m²</span></div>
<div class="room-chip">Gästezimmer <span class="room-chip-area">11,5</span></div>
<div class="room-chip">Badezimmer <span class="room-chip-area">9,8 m²</span></div>
<div class="room-chip">Küche <span class="room-chip-area">18,4 m²</span></div>
<div class="room-chip">Schlafzimmer <span class="room-chip-area">18,0 m²</span></div>
<div class="room-chip">
Flur
<span class="room-chip-area">20,1</span>
</div>
<div class="room-chip">
Wohnzimmer
<span class="room-chip-area">24,7 m²</span>
</div>
<div class="room-chip">
Gästezimmer
<span class="room-chip-area">11,5 m²</span>
</div>
<div class="room-chip">
Badezimmer
<span class="room-chip-area">9,8 m²</span>
</div>
<div class="room-chip">
Küche
<span class="room-chip-area">18,4 m²</span>
</div>
<div class="room-chip">
Schlafzimmer
<span class="room-chip-area">18,0 m²</span>
</div>
</div>
</div>
</div>
@@ -194,12 +263,30 @@
</div>
<div class="floor-body">
<div class="floor-rooms-grid">
<div class="room-chip">Flur <span class="room-chip-area">13,9 m²</span></div>
<div class="room-chip">Kinderzimmer 1 <span class="room-chip-area">21,7 m²</span></div>
<div class="room-chip">Kinderzimmer 2 <span class="room-chip-area">15,7</span></div>
<div class="room-chip">Spielzimmer <span class="room-chip-area">6,3 m²</span></div>
<div class="room-chip">Ankleidezimmer <span class="room-chip-area">1,4 m²</span></div>
<div class="room-chip">Dachterrasse <span class="room-chip-area">35,8 m²</span></div>
<div class="room-chip">
Flur
<span class="room-chip-area">13,9</span>
</div>
<div class="room-chip">
Kinderzimmer 1
<span class="room-chip-area">21,7 m²</span>
</div>
<div class="room-chip">
Kinderzimmer 2
<span class="room-chip-area">15,7 m²</span>
</div>
<div class="room-chip">
Spielzimmer
<span class="room-chip-area">6,3 m²</span>
</div>
<div class="room-chip">
Ankleidezimmer
<span class="room-chip-area">1,4 m²</span>
</div>
<div class="room-chip">
Dachterrasse
<span class="room-chip-area">35,8 m²</span>
</div>
</div>
</div>
</div>
@@ -213,14 +300,17 @@
</div>
<div class="floor-body">
<div class="floor-rooms-grid">
<div class="room-chip">Dachboden (ungeheizt) <span class="room-chip-area">52 m²</span></div>
<div class="room-chip">
Dachboden (ungeheizt)
<span class="room-chip-area">52 m²</span>
</div>
</div>
</div>
</div>
</section>
</div>
</section>
<section class="pricing-section" id="miete">
<section class="pricing-section" id="miete">
<div class="pricing-inner">
<div class="section-eyebrow">Mietkonditionen</div>
<h2>Transparente Preisgestaltung</h2>
@@ -242,62 +332,107 @@
</div>
</div>
<div class="price-note">
<div class="pn-item"><strong>Verfügbarkeit</strong>Ab sofort · unbefristete Laufzeit</div>
<div class="pn-item"><strong>Nebenkosten</strong>Vorauszahlung 300 €/Monat, jährliche Abrechnung</div>
<div class="pn-item"><strong>Energieausweis</strong>Wird bei Mietbeginn übergeben · Erdgasheizung</div>
<div class="pn-item"><strong>Haustiere</strong>Auf Anfrage</div>
<div class="pn-item">
<strong>Verfügbarkeit</strong>
Ab sofort · unbefristete Laufzeit
</div>
<div class="pn-item">
<strong>Nebenkosten</strong>
Vorauszahlung 300 €/Monat, jährliche Abrechnung
</div>
<div class="pn-item">
<strong>Energieausweis</strong>
Wird bei Mietbeginn übergeben · Erdgasheizung
</div>
<div class="pn-item">
<strong>Haustiere</strong>
Auf Anfrage
</div>
</div>
</section>
</div>
</section>
<section class="lage-section" id="lage">
<section class="lage-section" id="lage">
<div class="section-eyebrow">Standort</div>
<h2>Zentral und ruhig zugleich</h2>
<div class="lage-grid">
<div class="lage-item">
<div class="lage-icon">🛒</div>
<div><div class="lage-title">Einkaufen & Versorgung</div><div class="lage-desc">Supermärkte, Ärzte, Apotheken und Schulen sind fußläufig erreichbar</div></div>
<div>
<div class="lage-title">Einkaufen & Versorgung</div>
<div class="lage-desc">
Supermärkte, Ärzte, Apotheken und Schulen sind fußläufig erreichbar
</div>
</div>
</div>
<div class="lage-item">
<div class="lage-icon">🚌</div>
<div><div class="lage-title">Öffentlicher Nahverkehr</div><div class="lage-desc">Zentrale Bushaltestelle ca. 200 m entfernt — direkte Verbindungen in die Region</div></div>
<div>
<div class="lage-title">Öffentlicher Nahverkehr</div>
<div class="lage-desc">
Zentrale Bushaltestelle ca. 200 m entfernt — direkte Verbindungen in die Region
</div>
</div>
</div>
<div class="lage-item">
<div class="lage-icon">🏛</div>
<div><div class="lage-title">Innenstadt Schleusingen</div><div class="lage-desc">Wochenmarkt und Stadtmitte nur ca. 500 m entfernt</div></div>
<div>
<div class="lage-title">Innenstadt Schleusingen</div>
<div class="lage-desc">Wochenmarkt und Stadtmitte nur ca. 500 m entfernt</div>
</div>
</div>
<div class="lage-item">
<div class="lage-icon">📍</div>
<div><div class="lage-title">Genaue Adresse</div><div class="lage-desc">Schleusinger Bahnhofstraße 10<br>98533 Schleusingen, Thüringen</div></div>
<div>
<div class="lage-title">Genaue Adresse</div>
<div class="lage-desc">
Schleusinger Bahnhofstraße 10
<br />
98533 Schleusingen, Thüringen
</div>
</div>
</section>
</div>
</div>
</section>
<section class="contact-section" id="kontakt">
<section class="contact-section" id="kontakt">
<div class="contact-inner">
<div class="section-eyebrow">Kontakt</div>
<h2>Interesse?<br><em>Schreiben Sie uns.</em></h2>
<p>Wir freuen uns über Ihre Anfrage und melden uns innerhalb von 24 Stunden. Besichtigungstermine sind jederzeit möglich.</p>
<h2>
Interesse?
<br />
<em>Schreiben Sie uns.</em>
</h2>
<p>
Wir freuen uns über Ihre Anfrage und melden uns innerhalb von 24 Stunden.
Besichtigungstermine sind jederzeit möglich.
</p>
<div class="contact-form">
<form id="contactForm">
<div class="form-row">
<div class="form-field">
<label for="fname">Vorname</label>
<input type="text" id="fname" name="fname" placeholder="Max" required>
<input type="text" id="fname" name="fname" placeholder="Max" required />
</div>
<div class="form-field">
<label for="lname">Nachname</label>
<input type="text" id="lname" name="lname" placeholder="Mustermann" required>
<input type="text" id="lname" name="lname" placeholder="Mustermann" required />
</div>
</div>
<div class="form-row">
<div class="form-field">
<label for="email">E-Mail</label>
<input type="email" id="email" name="email" placeholder="max@beispiel.de" required>
<input
type="email"
id="email"
name="email"
placeholder="max@beispiel.de"
required
/>
</div>
<div class="form-field">
<label for="phone">Telefon</label>
<input type="tel" id="phone" name="phone" placeholder="+49 ...">
<input type="tel" id="phone" name="phone" placeholder="+49 ..." />
</div>
</div>
<div class="form-row">
@@ -313,33 +448,38 @@
<div class="form-row">
<div class="form-field full">
<label for="message">Nachricht</label>
<textarea id="message" name="message" rows="4" placeholder="Ihre Nachricht ..."></textarea>
<textarea
id="message"
name="message"
rows="4"
placeholder="Ihre Nachricht ..."
></textarea>
</div>
</div>
<button type="submit" class="btn-submit">Anfrage absenden</button>
</form>
<div class="form-success" id="formSuccess">
<p>Vielen Dank für Ihre Anfrage!</p>
<br>
<br />
<small>Wir melden uns schnellstmöglich bei Ihnen.</small>
</div>
</div>
</div>
</section>
</section>
<footer>
<footer>
<div class="footer-logo">Bahnhofstraße 10 · Schleusingen</div>
<div class="footer-links">
<a href="#">Impressum</a>
<a href="#">Datenschutz</a>
</div>
</footer>
</footer>
<div class="lightbox" id="lightbox">
<div class="lightbox" id="lightbox">
<button class="lightbox-close" id="lightboxClose">&times;</button>
<img src="" id="lightboxImg" alt="Vollbild">
</div>
<img src="" id="lightboxImg" alt="Vollbild" />
</div>
<script src="js/haus-schleusingen.js"></script>
</body>
<script src="js/haus-schleusingen.js"></script>
</body>
</html>

View File

@@ -1,70 +1,76 @@
$(function() {
$(function () {
// Navbar scroll
$(window).on('scroll', function() {
if ($(this).scrollTop() > 60) $('#navbar').addClass('scrolled');
else $('#navbar').removeClass('scrolled');
$(window).on("scroll", function () {
if ($(this).scrollTop() > 60) $("#navbar").addClass("scrolled");
else $("#navbar").removeClass("scrolled");
});
// Hero animation on load
setTimeout(function() {
$('#heroContent').addClass('visible');
$('#heroBg').addClass('loaded');
setTimeout(function () {
$("#heroContent").addClass("visible");
$("#heroBg").addClass("loaded");
}, 200);
// Scroll animations
function checkVisible() {
$('.fact, [data-animate]').each(function() {
$(".fact, [data-animate]").each(function () {
var el = $(this);
var top = el.offset().top;
var windowBottom = $(window).scrollTop() + $(window).height();
if (windowBottom > top + 60) {
el.addClass('visible');
el.css({opacity: 1, transform: 'translateY(0)'});
el.addClass("visible");
el.css({ opacity: 1, transform: "translateY(0)" });
}
});
}
$('[data-animate]').css({opacity: 0, transform: 'translateY(30px)', transition: 'opacity 0.8s ease, transform 0.8s ease'});
$(window).on('scroll', checkVisible);
$("[data-animate]").css({
opacity: 0,
transform: "translateY(30px)",
transition: "opacity 0.8s ease, transform 0.8s ease",
});
$(window).on("scroll", checkVisible);
checkVisible();
// Floor accordion
$('.floor-header').on('click', function() {
var item = $(this).closest('.floor-item');
var isOpen = item.hasClass('open');
$('.floor-item').removeClass('open');
$('.floor-body').slideUp(300);
$(".floor-header").on("click", function () {
var item = $(this).closest(".floor-item");
var isOpen = item.hasClass("open");
$(".floor-item").removeClass("open");
$(".floor-body").slideUp(300);
if (!isOpen) {
item.addClass('open');
item.find('.floor-body').slideDown(300);
item.addClass("open");
item.find(".floor-body").slideDown(300);
}
});
// Lightbox gallery grid items
$(document).on('click', '.grid-item', function() {
var src = $(this).data('img') || $(this).find('img').attr('src');
$('#lightboxImg').attr('src', src);
$('#lightbox').addClass('open');
$('body').css('overflow', 'hidden');
$(document).on("click", ".grid-item", function () {
var src = $(this).data("img") || $(this).find("img").attr("src");
$("#lightboxImg").attr("src", src);
$("#lightbox").addClass("open");
$("body").css("overflow", "hidden");
});
$('#lightboxClose, #lightbox').on('click', function(e) {
$("#lightboxClose, #lightbox").on("click", function (e) {
if (e.target === this) {
$('#lightbox').removeClass('open');
$('body').css('overflow', '');
$("#lightbox").removeClass("open");
$("body").css("overflow", "");
}
});
$(document).on('keydown', function(e) {
if (e.key === 'Escape') { $('#lightbox').removeClass('open'); $('body').css('overflow', ''); }
$(document).on("keydown", function (e) {
if (e.key === "Escape") {
$("#lightbox").removeClass("open");
$("body").css("overflow", "");
}
});
// Form submit
$('#contactForm').on('submit', function(e) {
$("#contactForm").on("submit", function (e) {
e.preventDefault();
var btn = $(this).find('.btn-submit');
btn.text('Wird gesendet...').prop('disabled', true);
setTimeout(function() {
$('#contactForm').hide();
$('#formSuccess').fadeIn(400);
var btn = $(this).find(".btn-submit");
btn.text("Wird gesendet...").prop("disabled", true);
setTimeout(function () {
$("#contactForm").hide();
$("#formSuccess").fadeIn(400);
}, 1200);
});
});

54
package.json Normal file
View File

@@ -0,0 +1,54 @@
{
"name": "landingpage-haus-schleusingen",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"lint:html": "htmlhint \"**/*.html\"",
"lint:css": "stylelint \"css/**/*.css\" \"fonts/**/*.css\"",
"lint:js": "eslint \"js/**/*.js\" --ignore-pattern \"**/*.min.js\"",
"lint": "npm run lint:html && npm run lint:css && npm run lint:js",
"format": "prettier --write \"**/*.{html,css,js,json,md}\" --ignore-path .prettierignore",
"format:check": "prettier --check \"**/*.{html,css,js,json,md}\" --ignore-path .prettierignore",
"prepare": "husky"
},
"lint-staged": {
"*.{html}": [
"htmlhint",
"prettier --write"
],
"*.{css}": [
"stylelint --fix",
"prettier --write"
],
"*.{js}": [
"eslint --fix",
"prettier --write"
],
"*.{json,md}": [
"prettier --write"
]
},
"repository": {
"type": "git",
"url": "https://git.home.kies-media.de/greggy/landingpage-haus-schleusingen.git"
},
"keywords": [],
"author": "",
"license": "ISC",
"type": "commonjs",
"devDependencies": {
"@eslint/js": "^10.0.1",
"eslint": "^10.3.0",
"eslint-config-prettier": "^10.1.8",
"eslint-plugin-prettier": "^5.5.5",
"globals": "^17.6.0",
"htmlhint": "^1.9.2",
"husky": "^9.1.7",
"lint-staged": "^16.4.0",
"prettier": "^3.8.3",
"stylelint": "^16.26.1",
"stylelint-config-standard": "^36.0.1",
"stylelint-prettier": "^5.0.3"
}
}