purinto-website/assets/js/site.js
Denise Krölling 1a63f66463 Website der Purinto GmbH aufsetzen
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>
2026-08-13 13:07:08 +02:00

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());
})();