967 lines
No EOL
28 KiB
HTML
967 lines
No EOL
28 KiB
HTML
<!DOCTYPE html>
|
||
<html lang="de">
|
||
<head>
|
||
<meta charset="UTF-8">
|
||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||
<title>Knotenwelt – Handgemachtes Makramee</title>
|
||
<link rel="preconnect" href="https://fonts.googleapis.com">
|
||
<link href="https://fonts.googleapis.com/css2?family=Cormorant+Garamond:ital,wght@0,300;0,400;0,600;1,300;1,400&family=DM+Sans:wght@300;400;500&display=swap" rel="stylesheet">
|
||
<style>
|
||
:root {
|
||
--cream: #faf6f0;
|
||
--warm-white: #fff9f2;
|
||
--sand: #e8ddd0;
|
||
--terra: #c4845a;
|
||
--terra-dark: #a06540;
|
||
--brown: #5c3d2e;
|
||
--text: #3a2a1f;
|
||
--text-light: #8a7060;
|
||
--rope: #d4b896;
|
||
}
|
||
|
||
* { margin: 0; padding: 0; box-sizing: border-box; }
|
||
|
||
html { scroll-behavior: smooth; }
|
||
|
||
body {
|
||
font-family: 'DM Sans', sans-serif;
|
||
background: var(--cream);
|
||
color: var(--text);
|
||
overflow-x: hidden;
|
||
}
|
||
|
||
/* ── NAV ── */
|
||
nav {
|
||
position: fixed; top: 0; left: 0; right: 0;
|
||
z-index: 100;
|
||
padding: 1.2rem 3rem;
|
||
display: flex; align-items: center; justify-content: space-between;
|
||
background: rgba(250,246,240,0.85);
|
||
backdrop-filter: blur(12px);
|
||
border-bottom: 1px solid rgba(196,132,90,0.15);
|
||
}
|
||
|
||
.nav-logo {
|
||
font-family: 'Cormorant Garamond', serif;
|
||
font-size: 1.6rem;
|
||
font-weight: 300;
|
||
color: var(--brown);
|
||
letter-spacing: 0.05em;
|
||
}
|
||
.nav-logo span { color: var(--terra); font-style: italic; }
|
||
|
||
.nav-links {
|
||
display: flex; gap: 2rem; list-style: none;
|
||
align-items: center;
|
||
}
|
||
.nav-links a {
|
||
text-decoration: none;
|
||
color: var(--text-light);
|
||
font-size: 0.85rem;
|
||
font-weight: 400;
|
||
letter-spacing: 0.08em;
|
||
text-transform: uppercase;
|
||
transition: color 0.2s;
|
||
}
|
||
.nav-links a:hover { color: var(--terra); }
|
||
|
||
.btn-login {
|
||
background: var(--terra);
|
||
color: white !important;
|
||
padding: 0.5rem 1.3rem;
|
||
border-radius: 50px;
|
||
transition: background 0.2s !important;
|
||
}
|
||
.btn-login:hover { background: var(--terra-dark) !important; color: white !important; }
|
||
|
||
/* ── HERO / SLIDESHOW ── */
|
||
.hero {
|
||
min-height: 100vh;
|
||
display: grid;
|
||
grid-template-columns: 1fr 1fr;
|
||
padding-top: 72px;
|
||
}
|
||
|
||
.hero-text {
|
||
display: flex; flex-direction: column; justify-content: center;
|
||
padding: 5rem 4rem 5rem 6rem;
|
||
animation: fadeUp 0.9s ease both;
|
||
}
|
||
|
||
.hero-tag {
|
||
font-size: 0.75rem;
|
||
font-weight: 500;
|
||
letter-spacing: 0.2em;
|
||
text-transform: uppercase;
|
||
color: var(--terra);
|
||
margin-bottom: 1.5rem;
|
||
}
|
||
|
||
.hero-title {
|
||
font-family: 'Cormorant Garamond', serif;
|
||
font-size: clamp(3rem, 5vw, 4.5rem);
|
||
font-weight: 300;
|
||
line-height: 1.1;
|
||
color: var(--brown);
|
||
margin-bottom: 1.5rem;
|
||
}
|
||
.hero-title em { font-style: italic; color: var(--terra); }
|
||
|
||
.hero-sub {
|
||
font-size: 1rem;
|
||
color: var(--text-light);
|
||
line-height: 1.7;
|
||
max-width: 400px;
|
||
margin-bottom: 2.5rem;
|
||
}
|
||
|
||
.hero-buttons {
|
||
display: flex; gap: 1rem; flex-wrap: wrap;
|
||
}
|
||
|
||
.btn-primary {
|
||
background: var(--terra);
|
||
color: white;
|
||
border: none;
|
||
padding: 0.85rem 2rem;
|
||
border-radius: 50px;
|
||
font-family: 'DM Sans', sans-serif;
|
||
font-size: 0.9rem;
|
||
font-weight: 500;
|
||
cursor: pointer;
|
||
text-decoration: none;
|
||
transition: background 0.2s, transform 0.15s;
|
||
}
|
||
.btn-primary:hover { background: var(--terra-dark); transform: translateY(-1px); }
|
||
|
||
.btn-ghost {
|
||
background: transparent;
|
||
color: var(--brown);
|
||
border: 1.5px solid var(--sand);
|
||
padding: 0.85rem 2rem;
|
||
border-radius: 50px;
|
||
font-family: 'DM Sans', sans-serif;
|
||
font-size: 0.9rem;
|
||
font-weight: 400;
|
||
cursor: pointer;
|
||
text-decoration: none;
|
||
transition: border-color 0.2s, transform 0.15s;
|
||
}
|
||
.btn-ghost:hover { border-color: var(--terra); transform: translateY(-1px); }
|
||
|
||
/* ── SLIDESHOW ── */
|
||
.hero-slideshow {
|
||
position: relative;
|
||
overflow: hidden;
|
||
background: var(--sand);
|
||
}
|
||
|
||
.slide {
|
||
position: absolute; inset: 0;
|
||
opacity: 0;
|
||
transition: opacity 1.2s ease;
|
||
display: flex; align-items: center; justify-content: center;
|
||
}
|
||
.slide.active { opacity: 1; }
|
||
|
||
/* CSS Makramee-Muster als Platzhalter */
|
||
.slide-1 { background: linear-gradient(135deg, #e8d5c0 0%, #d4b896 50%, #c49a72 100%); }
|
||
.slide-2 { background: linear-gradient(135deg, #c9b49a 0%, #b89870 50%, #d4a878 100%); }
|
||
.slide-3 { background: linear-gradient(135deg, #dfc9ae 0%, #c8a882 50%, #b8906a 100%); }
|
||
|
||
.slide-pattern {
|
||
width: 80%;
|
||
max-width: 360px;
|
||
aspect-ratio: 3/4;
|
||
position: relative;
|
||
}
|
||
|
||
/* Makramee Rope-Knoten SVG Pattern */
|
||
.slide-pattern svg {
|
||
width: 100%; height: 100%;
|
||
opacity: 0.35;
|
||
}
|
||
|
||
.slide-caption {
|
||
position: absolute;
|
||
bottom: 2rem; left: 2rem; right: 2rem;
|
||
color: white;
|
||
font-family: 'Cormorant Garamond', serif;
|
||
font-size: 1.4rem;
|
||
font-style: italic;
|
||
font-weight: 300;
|
||
text-shadow: 0 2px 20px rgba(0,0,0,0.3);
|
||
}
|
||
|
||
.slide-dots {
|
||
position: absolute;
|
||
bottom: 1.5rem; right: 2rem;
|
||
display: flex; gap: 0.5rem;
|
||
}
|
||
.dot {
|
||
width: 6px; height: 6px;
|
||
border-radius: 50%;
|
||
background: rgba(255,255,255,0.4);
|
||
cursor: pointer;
|
||
transition: background 0.2s;
|
||
}
|
||
.dot.active { background: white; }
|
||
|
||
/* ── ABOUT SECTION ── */
|
||
.section {
|
||
padding: 7rem 6rem;
|
||
}
|
||
|
||
.section-tag {
|
||
font-size: 0.75rem;
|
||
letter-spacing: 0.2em;
|
||
text-transform: uppercase;
|
||
color: var(--terra);
|
||
font-weight: 500;
|
||
margin-bottom: 1rem;
|
||
}
|
||
|
||
.section-title {
|
||
font-family: 'Cormorant Garamond', serif;
|
||
font-size: clamp(2rem, 3.5vw, 3rem);
|
||
font-weight: 300;
|
||
color: var(--brown);
|
||
margin-bottom: 1.5rem;
|
||
line-height: 1.2;
|
||
}
|
||
|
||
.about-grid {
|
||
display: grid;
|
||
grid-template-columns: 1fr 1fr;
|
||
gap: 5rem;
|
||
align-items: center;
|
||
}
|
||
|
||
.about-text p {
|
||
color: var(--text-light);
|
||
line-height: 1.8;
|
||
margin-bottom: 1.2rem;
|
||
font-size: 0.95rem;
|
||
}
|
||
|
||
.about-features {
|
||
display: grid;
|
||
grid-template-columns: 1fr 1fr;
|
||
gap: 1.5rem;
|
||
margin-top: 2rem;
|
||
}
|
||
|
||
.feature-card {
|
||
background: var(--warm-white);
|
||
border: 1px solid var(--sand);
|
||
border-radius: 16px;
|
||
padding: 1.5rem;
|
||
transition: transform 0.2s, box-shadow 0.2s;
|
||
}
|
||
.feature-card:hover { transform: translateY(-3px); box-shadow: 0 8px 30px rgba(92,61,46,0.08); }
|
||
|
||
.feature-card h4 {
|
||
font-family: 'Cormorant Garamond', serif;
|
||
font-size: 1.1rem;
|
||
font-weight: 400;
|
||
color: var(--brown);
|
||
margin-bottom: 0.3rem;
|
||
}
|
||
|
||
.feature-card p {
|
||
font-size: 0.8rem;
|
||
color: var(--text-light);
|
||
line-height: 1.5;
|
||
}
|
||
|
||
.about-visual {
|
||
position: relative;
|
||
}
|
||
|
||
.about-img-placeholder {
|
||
width: 100%;
|
||
aspect-ratio: 4/5;
|
||
background: linear-gradient(160deg, var(--sand) 0%, var(--rope) 100%);
|
||
border-radius: 24px;
|
||
display: flex; align-items: center; justify-content: center;
|
||
overflow: hidden;
|
||
position: relative;
|
||
}
|
||
|
||
.about-img-placeholder::before {
|
||
content: '';
|
||
position: absolute; inset: 0;
|
||
background: repeating-linear-gradient(
|
||
45deg,
|
||
transparent,
|
||
transparent 20px,
|
||
rgba(255,255,255,0.08) 20px,
|
||
rgba(255,255,255,0.08) 21px
|
||
);
|
||
}
|
||
|
||
.about-img-text {
|
||
font-family: 'Cormorant Garamond', serif;
|
||
font-size: 1.1rem;
|
||
font-style: italic;
|
||
color: white;
|
||
text-align: center;
|
||
padding: 2rem;
|
||
text-shadow: 0 2px 10px rgba(0,0,0,0.2);
|
||
}
|
||
|
||
.about-badge {
|
||
position: absolute;
|
||
bottom: -1rem; right: -1rem;
|
||
background: var(--terra);
|
||
color: white;
|
||
border-radius: 50%;
|
||
width: 110px; height: 110px;
|
||
display: flex; flex-direction: column; align-items: center; justify-content: center;
|
||
text-align: center;
|
||
box-shadow: 0 4px 20px rgba(196,132,90,0.4);
|
||
}
|
||
.about-badge span:first-child {
|
||
font-family: 'Cormorant Garamond', serif;
|
||
font-size: 1.8rem;
|
||
font-weight: 300;
|
||
line-height: 1;
|
||
}
|
||
.about-badge span:last-child {
|
||
font-size: 0.65rem;
|
||
letter-spacing: 0.1em;
|
||
text-transform: uppercase;
|
||
opacity: 0.9;
|
||
}
|
||
|
||
/* ── STORE INFO ── */
|
||
.store-section {
|
||
background: var(--warm-white);
|
||
padding: 5rem 6rem;
|
||
border-top: 1px solid var(--sand);
|
||
border-bottom: 1px solid var(--sand);
|
||
}
|
||
|
||
.store-grid {
|
||
display: grid;
|
||
grid-template-columns: 1fr 1fr;
|
||
gap: 4rem;
|
||
align-items: start;
|
||
max-width: 900px;
|
||
margin: 3rem auto 0;
|
||
}
|
||
|
||
.store-info-block h3 {
|
||
font-family: 'Cormorant Garamond', serif;
|
||
font-size: 1.4rem;
|
||
font-weight: 400;
|
||
color: var(--brown);
|
||
margin-bottom: 1rem;
|
||
}
|
||
|
||
.store-info-block p, .store-info-block address {
|
||
font-style: normal;
|
||
color: var(--text-light);
|
||
line-height: 1.8;
|
||
font-size: 0.9rem;
|
||
}
|
||
|
||
.insta-link {
|
||
display: inline-flex; align-items: center; gap: 0.6rem;
|
||
margin-top: 1.5rem;
|
||
color: var(--terra);
|
||
text-decoration: none;
|
||
font-weight: 500;
|
||
font-size: 0.9rem;
|
||
transition: gap 0.2s;
|
||
}
|
||
.insta-link:hover { gap: 0.9rem; }
|
||
|
||
.insta-icon {
|
||
width: 36px; height: 36px;
|
||
background: linear-gradient(135deg, #f58529, #dd2a7b, #8134af);
|
||
border-radius: 8px;
|
||
display: flex; align-items: center; justify-content: center;
|
||
color: white;
|
||
font-size: 1.1rem;
|
||
}
|
||
|
||
/* ── CONTACT ── */
|
||
.contact-section {
|
||
padding: 7rem 6rem;
|
||
max-width: 700px;
|
||
margin: 0 auto;
|
||
text-align: center;
|
||
}
|
||
|
||
.contact-form {
|
||
margin-top: 3rem;
|
||
text-align: left;
|
||
display: flex; flex-direction: column; gap: 1.2rem;
|
||
}
|
||
|
||
.form-row {
|
||
display: grid; grid-template-columns: 1fr 1fr; gap: 1rem;
|
||
}
|
||
|
||
.form-group {
|
||
display: flex; flex-direction: column; gap: 0.4rem;
|
||
}
|
||
|
||
.form-group label {
|
||
font-size: 0.75rem;
|
||
font-weight: 500;
|
||
letter-spacing: 0.1em;
|
||
text-transform: uppercase;
|
||
color: var(--text-light);
|
||
}
|
||
|
||
.form-group input,
|
||
.form-group textarea {
|
||
background: var(--warm-white);
|
||
border: 1.5px solid var(--sand);
|
||
border-radius: 10px;
|
||
padding: 0.8rem 1rem;
|
||
font-family: 'DM Sans', sans-serif;
|
||
font-size: 0.9rem;
|
||
color: var(--text);
|
||
outline: none;
|
||
transition: border-color 0.2s;
|
||
resize: none;
|
||
}
|
||
|
||
.form-group input:focus,
|
||
.form-group textarea:focus { border-color: var(--terra); }
|
||
|
||
.form-group textarea { min-height: 130px; }
|
||
|
||
.form-submit {
|
||
align-self: flex-start;
|
||
}
|
||
|
||
.success-msg {
|
||
display: none;
|
||
background: #f0faf5;
|
||
border: 1px solid #a8d8bc;
|
||
color: #2d6a4f;
|
||
padding: 1rem 1.5rem;
|
||
border-radius: 10px;
|
||
font-size: 0.9rem;
|
||
}
|
||
|
||
/* ── MODAL (Login/Register) ── */
|
||
.modal-overlay {
|
||
display: none;
|
||
position: fixed; inset: 0;
|
||
background: rgba(58,42,31,0.4);
|
||
backdrop-filter: blur(6px);
|
||
z-index: 200;
|
||
align-items: center; justify-content: center;
|
||
}
|
||
.modal-overlay.open { display: flex; }
|
||
|
||
.modal {
|
||
background: var(--warm-white);
|
||
border-radius: 24px;
|
||
padding: 2.5rem;
|
||
width: 90%; max-width: 420px;
|
||
position: relative;
|
||
animation: fadeUp 0.3s ease;
|
||
box-shadow: 0 20px 60px rgba(58,42,31,0.2);
|
||
}
|
||
|
||
.modal-close {
|
||
position: absolute; top: 1.2rem; right: 1.2rem;
|
||
background: none; border: none;
|
||
font-size: 1.3rem; cursor: pointer;
|
||
color: var(--text-light);
|
||
line-height: 1;
|
||
}
|
||
|
||
.modal-title {
|
||
font-family: 'Cormorant Garamond', serif;
|
||
font-size: 1.8rem;
|
||
font-weight: 300;
|
||
color: var(--brown);
|
||
margin-bottom: 0.3rem;
|
||
}
|
||
|
||
.modal-sub {
|
||
font-size: 0.85rem;
|
||
color: var(--text-light);
|
||
margin-bottom: 2rem;
|
||
}
|
||
|
||
.modal-tabs {
|
||
display: flex; gap: 0;
|
||
border: 1.5px solid var(--sand);
|
||
border-radius: 50px;
|
||
margin-bottom: 2rem;
|
||
overflow: hidden;
|
||
}
|
||
|
||
.modal-tab {
|
||
flex: 1;
|
||
padding: 0.55rem;
|
||
border: none;
|
||
background: transparent;
|
||
font-family: 'DM Sans', sans-serif;
|
||
font-size: 0.85rem;
|
||
cursor: pointer;
|
||
color: var(--text-light);
|
||
border-radius: 50px;
|
||
transition: all 0.2s;
|
||
}
|
||
.modal-tab.active { background: var(--terra); color: white; }
|
||
|
||
.modal-form { display: flex; flex-direction: column; gap: 1rem; }
|
||
|
||
.modal-form input {
|
||
background: var(--cream);
|
||
border: 1.5px solid var(--sand);
|
||
border-radius: 10px;
|
||
padding: 0.75rem 1rem;
|
||
font-family: 'DM Sans', sans-serif;
|
||
font-size: 0.9rem;
|
||
color: var(--text);
|
||
outline: none;
|
||
transition: border-color 0.2s;
|
||
width: 100%;
|
||
}
|
||
.modal-form input:focus { border-color: var(--terra); }
|
||
|
||
/* ── FOOTER ── */
|
||
footer {
|
||
background: var(--brown);
|
||
color: rgba(255,255,255,0.6);
|
||
padding: 3rem 6rem;
|
||
display: flex;
|
||
align-items: center; justify-content: space-between;
|
||
flex-wrap: wrap; gap: 1rem;
|
||
}
|
||
|
||
.footer-logo {
|
||
font-family: 'Cormorant Garamond', serif;
|
||
font-size: 1.4rem;
|
||
font-weight: 300;
|
||
color: white;
|
||
}
|
||
.footer-logo span { font-style: italic; color: var(--terra); }
|
||
|
||
footer p { font-size: 0.8rem; }
|
||
|
||
footer a { color: rgba(255,255,255,0.5); text-decoration: none; transition: color 0.2s; }
|
||
footer a:hover { color: var(--terra); }
|
||
|
||
/* ── ANIMATIONS ── */
|
||
@keyframes fadeUp {
|
||
from { opacity: 0; transform: translateY(24px); }
|
||
to { opacity: 1; transform: translateY(0); }
|
||
}
|
||
|
||
.reveal {
|
||
opacity: 0;
|
||
transform: translateY(30px);
|
||
transition: opacity 0.7s ease, transform 0.7s ease;
|
||
}
|
||
.reveal.visible { opacity: 1; transform: translateY(0); }
|
||
|
||
/* ── RESPONSIVE ── */
|
||
@media (max-width: 900px) {
|
||
nav { padding: 1rem 1.5rem; }
|
||
.nav-links { gap: 1rem; }
|
||
.hero { grid-template-columns: 1fr; min-height: auto; }
|
||
.hero-slideshow { height: 50vw; min-height: 300px; }
|
||
.hero-text { padding: 3rem 2rem; }
|
||
.section { padding: 4rem 2rem; }
|
||
.about-grid { grid-template-columns: 1fr; gap: 2rem; }
|
||
.store-section { padding: 4rem 2rem; }
|
||
.store-grid { grid-template-columns: 1fr; gap: 2rem; }
|
||
.contact-section { padding: 4rem 2rem; }
|
||
.form-row { grid-template-columns: 1fr; }
|
||
footer { padding: 2rem; flex-direction: column; text-align: center; }
|
||
}
|
||
</style>
|
||
</head>
|
||
<body>
|
||
|
||
<!-- NAV -->
|
||
<nav>
|
||
<div class="nav-logo">Knoten<span>welt</span></div>
|
||
<ul class="nav-links">
|
||
<li><a href="#about">Über uns</a></li>
|
||
<li><a href="#laden">Laden</a></li>
|
||
<li><a href="#kontakt">Kontakt</a></li>
|
||
<li><a href="#" class="btn-login" onclick="openModal(event)">Anmelden</a></li>
|
||
</ul>
|
||
</nav>
|
||
|
||
<!-- HERO -->
|
||
<section class="hero">
|
||
<div class="hero-text">
|
||
<p class="hero-tag">Handgemacht mit Liebe</p>
|
||
<h1 class="hero-title">
|
||
Makramee,<br>
|
||
<em>das Geschichten</em><br>
|
||
erzählt
|
||
</h1>
|
||
<p class="hero-sub">
|
||
Jedes Stück ein Unikat – geknüpft von Hand, mit Geduld und Herzblut.
|
||
Wandbehänge, Blumenampeln, Körbe und mehr.
|
||
</p>
|
||
<div class="hero-buttons">
|
||
<a href="#laden" class="btn-primary">Laden besuchen</a>
|
||
<a href="#kontakt" class="btn-ghost">Kontakt aufnehmen</a>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="hero-slideshow" id="slideshow">
|
||
<div class="slide active slide-1">
|
||
<div class="slide-pattern">
|
||
<svg viewBox="0 0 200 260" xmlns="http://www.w3.org/2000/svg">
|
||
<!-- Makramee Knoten Pattern -->
|
||
<g stroke="white" stroke-width="2.5" fill="none" stroke-linecap="round">
|
||
<!-- vertical ropes -->
|
||
<line x1="60" y1="0" x2="60" y2="260"/>
|
||
<line x1="100" y1="0" x2="100" y2="260"/>
|
||
<line x1="140" y1="0" x2="140" y2="260"/>
|
||
<!-- square knots row 1 -->
|
||
<path d="M60,40 Q80,30 100,40 Q80,50 60,40"/>
|
||
<path d="M100,40 Q120,30 140,40 Q120,50 100,40"/>
|
||
<!-- fringe bottom -->
|
||
<line x1="50" y1="200" x2="40" y2="260"/>
|
||
<line x1="60" y1="200" x2="55" y2="260"/>
|
||
<line x1="75" y1="200" x2="72" y2="260"/>
|
||
<line x1="90" y1="200" x2="90" y2="260"/>
|
||
<line x1="105" y1="200" x2="108" y2="260"/>
|
||
<line x1="120" y1="200" x2="125" y2="260"/>
|
||
<line x1="135" y1="200" x2="140" y2="260"/>
|
||
<line x1="150" y1="200" x2="160" y2="260"/>
|
||
<!-- more knots -->
|
||
<path d="M60,80 Q80,70 100,80 Q80,90 60,80"/>
|
||
<path d="M100,80 Q120,70 140,80 Q120,90 100,80"/>
|
||
<path d="M80,110 Q100,100 120,110 Q100,120 80,110"/>
|
||
<path d="M60,140 Q80,130 100,140 Q80,150 60,140"/>
|
||
<path d="M100,140 Q120,130 140,140 Q120,150 100,140"/>
|
||
<path d="M80,170 Q100,160 120,170 Q100,180 80,170"/>
|
||
</g>
|
||
</svg>
|
||
</div>
|
||
<div class="slide-caption">Wandbehänge & Dekor</div>
|
||
</div>
|
||
|
||
<div class="slide slide-2">
|
||
<div class="slide-pattern">
|
||
<svg viewBox="0 0 200 260" xmlns="http://www.w3.org/2000/svg">
|
||
<g stroke="white" stroke-width="2.5" fill="none" stroke-linecap="round">
|
||
<circle cx="100" cy="80" r="40" stroke-dasharray="8 4"/>
|
||
<line x1="70" y1="120" x2="55" y2="260"/>
|
||
<line x1="80" y1="120" x2="70" y2="260"/>
|
||
<line x1="95" y1="122" x2="90" y2="260"/>
|
||
<line x1="105" y1="122" x2="110" y2="260"/>
|
||
<line x1="120" y1="120" x2="130" y2="260"/>
|
||
<line x1="130" y1="120" x2="145" y2="260"/>
|
||
<path d="M60,140 Q100,130 140,140"/>
|
||
<path d="M65,155 Q100,145 135,155"/>
|
||
<path d="M70,170 Q100,160 130,170"/>
|
||
</g>
|
||
</svg>
|
||
</div>
|
||
<div class="slide-caption">Blumenampeln</div>
|
||
</div>
|
||
|
||
<div class="slide slide-3">
|
||
<div class="slide-pattern">
|
||
<svg viewBox="0 0 200 200" xmlns="http://www.w3.org/2000/svg">
|
||
<g stroke="white" stroke-width="2" fill="none" stroke-linecap="round">
|
||
<rect x="40" y="40" width="120" height="120" rx="8"/>
|
||
<rect x="55" y="55" width="90" height="90" rx="6"/>
|
||
<line x1="40" y1="70" x2="55" y2="70"/>
|
||
<line x1="40" y1="100" x2="55" y2="100"/>
|
||
<line x1="40" y1="130" x2="55" y2="130"/>
|
||
<line x1="145" y1="70" x2="160" y2="70"/>
|
||
<line x1="145" y1="100" x2="160" y2="100"/>
|
||
<line x1="145" y1="130" x2="160" y2="130"/>
|
||
<line x1="70" y1="40" x2="70" y2="55"/>
|
||
<line x1="100" y1="40" x2="100" y2="55"/>
|
||
<line x1="130" y1="40" x2="130" y2="55"/>
|
||
<line x1="70" y1="145" x2="70" y2="160"/>
|
||
<line x1="100" y1="145" x2="100" y2="160"/>
|
||
<line x1="130" y1="145" x2="130" y2="160"/>
|
||
<circle cx="100" cy="100" r="15"/>
|
||
</g>
|
||
</svg>
|
||
</div>
|
||
<div class="slide-caption">Körbe & Accessoires</div>
|
||
</div>
|
||
|
||
<div class="slide-dots">
|
||
<div class="dot active" onclick="goSlide(0)"></div>
|
||
<div class="dot" onclick="goSlide(1)"></div>
|
||
<div class="dot" onclick="goSlide(2)"></div>
|
||
</div>
|
||
</div>
|
||
</section>
|
||
|
||
<!-- ABOUT -->
|
||
<section class="section" id="about">
|
||
<div class="about-grid reveal">
|
||
<div class="about-text">
|
||
<p class="section-tag">Unsere Geschichte</p>
|
||
<h2 class="section-title">Handwerk mit<br>Herz & Seele</h2>
|
||
<p>Was als kleines Hobby begann, ist heute eine Leidenschaft geworden. Jedes Stück wird von Hand geknüpft – mit natürlichen Materialien, viel Zeit und noch mehr Liebe.</p>
|
||
<p>Von gemütlichen Wandbehängen bis zu eleganten Blumenampeln: Du findest alles in unserem kleinen Schrankladen oder kannst direkt anfragen.</p>
|
||
<div class="about-features">
|
||
<div class="feature-card">
|
||
<h4>100 % Handarbeit</h4>
|
||
<p>Kein Stück ist wie das andere.</p>
|
||
</div>
|
||
<div class="feature-card">
|
||
<h4>Natürliche Materialien</h4>
|
||
<p>Baumwolle, Jute & Leinen.</p>
|
||
</div>
|
||
<div class="feature-card">
|
||
<h4>Auf Wunsch</h4>
|
||
<p>Individuelle Bestellungen möglich.</p>
|
||
</div>
|
||
<div class="feature-card">
|
||
<h4>Mit Liebe gemacht</h4>
|
||
<p>Von einer Mutter, mit Herz.</p>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="about-visual">
|
||
<div class="about-img-placeholder">
|
||
<div class="about-img-text">
|
||
Hier kommen<br>deine schönsten<br>Produktfotos hin
|
||
</div>
|
||
</div>
|
||
<div class="about-badge">
|
||
<span>100%</span>
|
||
<span>Unikate</span>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</section>
|
||
|
||
<!-- STORE INFO -->
|
||
<section class="store-section" id="laden">
|
||
<div style="text-align:center">
|
||
<p class="section-tag">Wo du uns findest</p>
|
||
<h2 class="section-title">Im Laden & Online</h2>
|
||
</div>
|
||
<div class="store-grid reveal">
|
||
<div class="store-info-block">
|
||
<h3>Unser Schrankladen</h3>
|
||
<address>
|
||
Musterstraße 12<br>
|
||
01234 Musterstadt<br><br>
|
||
Mo–Sa: 10–18 Uhr<br>
|
||
So: nach Vereinbarung
|
||
</address>
|
||
</div>
|
||
<div class="store-info-block">
|
||
<h3>Folg uns auf Instagram</h3>
|
||
<p>Aktuelle Stücke, neue Ideen und ein Blick hinter die Kulissen – täglich frisch.</p>
|
||
<a href="https://instagram.com" target="_blank" class="insta-link">
|
||
<span class="insta-icon"></span>
|
||
@knotenwelt →
|
||
</a>
|
||
</div>
|
||
</div>
|
||
</section>
|
||
|
||
<!-- CONTACT -->
|
||
<section class="contact-section" id="kontakt">
|
||
<div class="reveal">
|
||
<p class="section-tag">Schreib uns</p>
|
||
<h2 class="section-title">Kontakt</h2>
|
||
<p style="color:var(--text-light); line-height:1.7; font-size:0.95rem">
|
||
Fragen, Wunschbestellungen oder einfach ein nettes Hallo – wir freuen uns über jede Nachricht.
|
||
</p>
|
||
<form class="contact-form" onsubmit="submitForm(event)">
|
||
<div class="form-row">
|
||
<div class="form-group">
|
||
<label>Name</label>
|
||
<input type="text" placeholder="Dein Name" required>
|
||
</div>
|
||
<div class="form-group">
|
||
<label>E-Mail</label>
|
||
<input type="email" placeholder="deine@email.de" required>
|
||
</div>
|
||
</div>
|
||
<div class="form-group">
|
||
<label>Nachricht</label>
|
||
<textarea placeholder="Deine Nachricht…" required></textarea>
|
||
</div>
|
||
<div class="success-msg" id="successMsg">
|
||
✓ Deine Nachricht wurde gesendet! Wir melden uns bald.
|
||
</div>
|
||
<button type="submit" class="btn-primary form-submit">Nachricht senden →</button>
|
||
</form>
|
||
</div>
|
||
</section>
|
||
|
||
<!-- FOOTER -->
|
||
<footer>
|
||
<div class="footer-logo">Knoten<span>welt</span></div>
|
||
<p>© 2025 Knotenwelt · Alle Rechte vorbehalten</p>
|
||
<div style="display:flex; gap:1.5rem; font-size:0.8rem">
|
||
<a href="#">Impressum</a>
|
||
<a href="#">Datenschutz</a>
|
||
</div>
|
||
</footer>
|
||
|
||
<!-- LOGIN MODAL -->
|
||
<div class="modal-overlay" id="modalOverlay" onclick="closeModalBg(event)">
|
||
<div class="modal">
|
||
<button class="modal-close" onclick="closeModal()">✕</button>
|
||
<h2 class="modal-title">Willkommen</h2>
|
||
<p class="modal-sub">Melde dich an oder erstelle ein Konto</p>
|
||
<div class="modal-tabs">
|
||
<button class="modal-tab active" onclick="switchTab(this,'login')">Anmelden</button>
|
||
<button class="modal-tab" onclick="switchTab(this,'register')">Registrieren</button>
|
||
</div>
|
||
<div id="loginForm">
|
||
<form class="modal-form" onsubmit="handleAuth(event,'login')">
|
||
<input type="email" name="email" placeholder="E-Mail-Adresse" required>
|
||
<input type="password" name="password" placeholder="Passwort" required>
|
||
<p class="auth-error" style="color:#c0392b;font-size:0.85rem;min-height:1.2em"></p>
|
||
<button type="submit" class="btn-primary" style="width:100%">Anmelden</button>
|
||
</form>
|
||
</div>
|
||
<div id="registerForm" style="display:none">
|
||
<form class="modal-form" onsubmit="handleAuth(event,'register')">
|
||
<input type="text" name="name" placeholder="Dein Name" required>
|
||
<input type="email" name="email" placeholder="E-Mail-Adresse" required>
|
||
<input type="password" name="password" placeholder="Passwort (min. 8 Zeichen)" required>
|
||
<p class="auth-error" style="color:#c0392b;font-size:0.85rem;min-height:1.2em"></p>
|
||
<button type="submit" class="btn-primary" style="width:100%">Konto erstellen</button>
|
||
</form>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<script>
|
||
// Slideshow
|
||
let current = 0;
|
||
const slides = document.querySelectorAll('.slide');
|
||
const dots = document.querySelectorAll('.dot');
|
||
|
||
function goSlide(n) {
|
||
slides[current].classList.remove('active');
|
||
dots[current].classList.remove('active');
|
||
current = n;
|
||
slides[current].classList.add('active');
|
||
dots[current].classList.add('active');
|
||
}
|
||
|
||
setInterval(() => goSlide((current + 1) % slides.length), 4000);
|
||
|
||
// Scroll reveal
|
||
const observer = new IntersectionObserver(entries => {
|
||
entries.forEach(e => { if (e.isIntersecting) e.target.classList.add('visible'); });
|
||
}, { threshold: 0.15 });
|
||
document.querySelectorAll('.reveal').forEach(el => observer.observe(el));
|
||
|
||
// Modal
|
||
function openModal(e) { e.preventDefault(); document.getElementById('modalOverlay').classList.add('open'); }
|
||
function closeModal() { document.getElementById('modalOverlay').classList.remove('open'); }
|
||
function closeModalBg(e) { if (e.target === document.getElementById('modalOverlay')) closeModal(); }
|
||
|
||
function switchTab(btn, tab) {
|
||
document.querySelectorAll('.modal-tab').forEach(t => t.classList.remove('active'));
|
||
btn.classList.add('active');
|
||
document.getElementById('loginForm').style.display = tab === 'login' ? '' : 'none';
|
||
document.getElementById('registerForm').style.display = tab === 'register' ? '' : 'none';
|
||
}
|
||
|
||
// ── Contact form ──────────────────────────────────────────
|
||
async function submitForm(e) {
|
||
e.preventDefault();
|
||
const btn = e.target.querySelector('button[type="submit"]');
|
||
const inputs = e.target.querySelectorAll('input, textarea');
|
||
const [nameEl, emailEl, msgEl] = inputs;
|
||
|
||
btn.disabled = true;
|
||
btn.textContent = 'Senden…';
|
||
|
||
try {
|
||
const res = await fetch('/api/contact', {
|
||
method: 'POST',
|
||
headers: { 'Content-Type': 'application/json' },
|
||
body: JSON.stringify({ name: nameEl.value, email: emailEl.value, message: msgEl.value }),
|
||
});
|
||
if (!res.ok) throw new Error();
|
||
document.getElementById('successMsg').style.display = 'block';
|
||
btn.style.display = 'none';
|
||
} catch {
|
||
btn.disabled = false;
|
||
btn.textContent = 'Nachricht senden →';
|
||
alert('Fehler beim Senden. Bitte versuche es später nochmal.');
|
||
}
|
||
}
|
||
|
||
// ── Auth ───────────────────────────────────────────────────
|
||
let currentUser = null;
|
||
|
||
// JWT aus localStorage laden
|
||
(async function checkAuth() {
|
||
const token = localStorage.getItem('token');
|
||
if (!token) return;
|
||
try {
|
||
const res = await fetch('/api/auth/me', { headers: { Authorization: `Bearer ${token}` } });
|
||
if (!res.ok) { localStorage.removeItem('token'); return; }
|
||
currentUser = await res.json();
|
||
updateNavUser();
|
||
} catch {}
|
||
})();
|
||
|
||
function updateNavUser() {
|
||
const loginLink = document.querySelector('.btn-login');
|
||
if (currentUser) {
|
||
loginLink.textContent = currentUser.name.split(' ')[0];
|
||
loginLink.onclick = logout;
|
||
}
|
||
}
|
||
|
||
function logout(e) {
|
||
e.preventDefault();
|
||
localStorage.removeItem('token');
|
||
currentUser = null;
|
||
document.querySelector('.btn-login').textContent = 'Anmelden';
|
||
document.querySelector('.btn-login').onclick = openModal;
|
||
}
|
||
|
||
async function handleAuth(e, mode) {
|
||
e.preventDefault();
|
||
const form = e.target;
|
||
const btn = form.querySelector('button');
|
||
const errorEl = form.querySelector('.auth-error');
|
||
errorEl.textContent = '';
|
||
btn.disabled = true;
|
||
|
||
const body = mode === 'register'
|
||
? { name: form.querySelector('[name=name]').value, email: form.querySelector('[name=email]').value, password: form.querySelector('[name=password]').value }
|
||
: { email: form.querySelector('[name=email]').value, password: form.querySelector('[name=password]').value };
|
||
|
||
try {
|
||
const res = await fetch(`/api/auth/${mode}`, {
|
||
method: 'POST',
|
||
headers: { 'Content-Type': 'application/json' },
|
||
body: JSON.stringify(body),
|
||
});
|
||
const data = await res.json();
|
||
if (!res.ok) { errorEl.textContent = data.error; btn.disabled = false; return; }
|
||
localStorage.setItem('token', data.token);
|
||
currentUser = data.user;
|
||
updateNavUser();
|
||
closeModal();
|
||
} catch {
|
||
errorEl.textContent = 'Verbindungsfehler';
|
||
btn.disabled = false;
|
||
}
|
||
}
|
||
</script>
|
||
</body>
|
||
</html> |