Statische Website ohne Build-Schritt: reines HTML, CSS und Vanilla-JS, lauffaehig auf beliebigem Webspace. Neun Seiten: Startseite, Dienstleistungen, Projekte, Ueber uns, Kontakt sowie Impressum, Datenschutz, Danke-Seite und 404. Kernstueck der Startseite ist die Stueckzahl-Achse: ein logarithmischer Regler von 1 bis 100.000 Stueck, der zur gewaehlten Menge Verfahren, Werkzeugkosten, Lieferzeit und Anwendungsfall ausgibt. Die dritte Zone ist optisch zurueckgenommen, weil Serienspritzguss ueber Partnerbetriebe laeuft und nicht zum eigenen Leistungsumfang gehoert. Der Leistungsumfang ist durchgehend auf FDM, SLA und SLA-gedruckte Formeinsaetze beschraenkt. Gestaltung nach Vorgabe: Anthrazit, Salbeigruen und Flieder als Akzent. Archivo, Public Sans und IBM Plex Mono werden lokal ausgeliefert statt ueber die Google-CDN eingebunden. Kontaktformular ueber Web3Forms mit Client-Validierung; der Access-Key ist noch ein Platzhalter. Alle Firmen- und Projektinhalte sind sichtbar als Platzhalter markiert, die Uebergabe-Checkliste steht in der README. Geprueft: WCAG-AA-Kontraste auf allen Seiten, kein horizontaler Ueberlauf von 320 bis 1920 px, Tastaturbedienung der Achse, feste Zeilenzahl der Hero-Headline. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
98 lines
3.3 KiB
JavaScript
98 lines
3.3 KiB
JavaScript
/* ==========================================================================
|
|
Purinto GmbH — Grundverhalten
|
|
Mobile-Navigation, Zustand der Kopfzeile beim Scrollen, Einblendungen.
|
|
Alles als Progressive Enhancement: ohne JS bleibt die Seite vollständig
|
|
bedienbar, nur ohne diese Verfeinerungen.
|
|
========================================================================== */
|
|
|
|
(function () {
|
|
"use strict";
|
|
|
|
/* --- Mobile-Navigation ------------------------------------------------- */
|
|
|
|
var schalter = document.querySelector("[data-nav-schalter]");
|
|
var nav = document.querySelector("[data-nav]");
|
|
|
|
if (schalter && nav) {
|
|
var navUmschalten = function (offen) {
|
|
nav.classList.toggle("ist-offen", offen);
|
|
schalter.setAttribute("aria-expanded", String(offen));
|
|
schalter.querySelector("[data-nav-schalter-text]").textContent = offen
|
|
? "Schließen"
|
|
: "Menü";
|
|
};
|
|
|
|
schalter.addEventListener("click", function () {
|
|
navUmschalten(schalter.getAttribute("aria-expanded") !== "true");
|
|
});
|
|
|
|
// Escape schließt das Menü und gibt den Fokus zurück.
|
|
document.addEventListener("keydown", function (e) {
|
|
if (e.key === "Escape" && nav.classList.contains("ist-offen")) {
|
|
navUmschalten(false);
|
|
schalter.focus();
|
|
}
|
|
});
|
|
|
|
// Beim Wechsel auf Desktop-Breite den mobilen Zustand zurücksetzen,
|
|
// sonst bleibt die Navigation unsichtbar hängen.
|
|
var breit = window.matchMedia("(min-width: 900px)");
|
|
var beiBreitenwechsel = function (mq) {
|
|
if (mq.matches) navUmschalten(false);
|
|
};
|
|
|
|
if (breit.addEventListener) {
|
|
breit.addEventListener("change", beiBreitenwechsel);
|
|
} else if (breit.addListener) {
|
|
breit.addListener(beiBreitenwechsel);
|
|
}
|
|
}
|
|
|
|
/* --- Kopfzeile bekommt beim Scrollen eine Trennlinie ------------------- */
|
|
|
|
var kopf = document.querySelector("[data-kopf]");
|
|
|
|
if (kopf) {
|
|
var kopfPruefen = function () {
|
|
kopf.classList.toggle("ist-gescrollt", window.scrollY > 8);
|
|
};
|
|
|
|
kopfPruefen();
|
|
window.addEventListener("scroll", kopfPruefen, { passive: true });
|
|
}
|
|
|
|
/* --- Dezente Einblendung beim Scrollen --------------------------------- */
|
|
|
|
var zuEnthuellen = document.querySelectorAll(".reveal");
|
|
|
|
if (zuEnthuellen.length) {
|
|
var ruhig = window.matchMedia("(prefers-reduced-motion: reduce)").matches;
|
|
|
|
if (ruhig || !("IntersectionObserver" in window)) {
|
|
// Ohne Beobachter oder bei reduzierter Bewegung sofort alles zeigen.
|
|
Array.prototype.forEach.call(zuEnthuellen, function (el) {
|
|
el.classList.add("ist-sichtbar");
|
|
});
|
|
} else {
|
|
var beobachter = new IntersectionObserver(
|
|
function (eintraege) {
|
|
eintraege.forEach(function (eintrag) {
|
|
if (!eintrag.isIntersecting) return;
|
|
eintrag.target.classList.add("ist-sichtbar");
|
|
beobachter.unobserve(eintrag.target);
|
|
});
|
|
},
|
|
{ rootMargin: "0px 0px -12% 0px", threshold: 0.08 }
|
|
);
|
|
|
|
Array.prototype.forEach.call(zuEnthuellen, function (el) {
|
|
beobachter.observe(el);
|
|
});
|
|
}
|
|
}
|
|
|
|
/* --- Jahreszahl in der Fußzeile ---------------------------------------- */
|
|
|
|
var jahr = document.querySelector("[data-jahr]");
|
|
if (jahr) jahr.textContent = String(new Date().getFullYear());
|
|
})();
|