markemacht/_markemacht.de/assets/js/app.js
Kevin Adametz 2a617e09cc
Some checks are pending
linter / quality (push) Waiting to run
tests / ci (8.3) (push) Waiting to run
tests / ci (8.4) (push) Waiting to run
tests / ci (8.5) (push) Waiting to run
Initial commit: Laravel-Skelett + Markenwissen-Verfassung + markemacht.de Web
Erfasst den vollständigen Projektstand mit drei Hauptbereichen:

1. Laravel 11 Application-Skelett
   - Standard-Setup (app/, bootstrap/, config/, database/, public/, resources/, routes/, storage/, tests/)
   - Composer + npm Konfiguration
   - Devcontainer für Laravel Sail (PHP/MySQL/Redis)
   - GitHub Actions Workflows (lint + tests)
   - Tailwind/Vite Build-Pipeline

2. docs/ – Wissensbasis "Marke macht." (Methodik-Verfassung)
   Stand nach Pflegerunde 2026-05-28:
   - 00_Methodik-Verfassung: Dok. 000 (v2.0.2) bis Dok. 013 (NEU) + Anhänge
   - 10_Quellen-Original: Wala, Sharp, Simon (read-only Quellen)
   - 20_Markenwissen: 25 abgeleitete MW-Dokumente (Wala_MW-WAL, Sharp_MW-HBG, Simon_MW-SIM)
   - 30_Synthese: Markenwissen_I_Synthese_Gesamt + Scorecard-Regeln
   - 40_Implementierung: 011b-Erweiterung
   - _Steuerung: 00_START_HIER, Serienübersicht, CHANGELOG.md

   Letzte methodische Eingriffe:
   - Methodik-Update v2.0 (Ownership Autorenschaft/Anwendung, Geltungsbereich Kernthese,
     Score-Ebenen DNA-Reifegrad, Preislogik Governance-Scope)
   - Dok. 013 NEU: Akquise- & Conversion-Logik (Auffahrten statt Funnel)
   - Rebranding brandwork.io → Brand Rules (brand-rules.com)
   - Schichtverletzungen behoben, Ordner-Symmetrie hergestellt, Verweise konsolidiert

3. _markemacht.de/ – Web-Frontend Design-Sandbox
   - Statische HTML-Entwürfe (Startseite, Methode, Manifest, Denken, Blog)
   - Design-System (warm_intellectualism, based_web_design)
   - Assets (CSS, JS, Favicon)

Konfiguration:
- .gitignore um .DS_Store und Thumbs.db erweitert
- Lokale Git-Identity gesetzt: Kevin Adametz <kevin.adametz@me.com>
- .env wird ignoriert (nur .env.example versioniert)

Konfliktregel: Bei Spannung zwischen Code und Methodik gilt die Methodik (Dok. 000).
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-28 16:01:54 +00:00

131 lines
3.8 KiB
JavaScript

/* markemacht.de — Interaktionen
* - Wirkung-Switch (monolithisch | editorial) + localStorage
* - Mobile Drawer
* - Scroll-Reveal (IntersectionObserver, max 400ms, ease-out)
* - Keyboard: ESC schließt Drawer
*/
(function () {
'use strict';
/* ---------- Wirkung ---------------------------------------------------- */
const STORAGE_KEY = 'mm-wirkung';
const VALID = ['monolith', 'editorial'];
const DEFAULT = 'monolith';
function getStored() {
try {
const v = localStorage.getItem(STORAGE_KEY);
return VALID.includes(v) ? v : null;
} catch (_) { return null; }
}
function applyMode(mode) {
if (!VALID.includes(mode)) mode = DEFAULT;
document.documentElement.setAttribute('data-theme', mode);
try { localStorage.setItem(STORAGE_KEY, mode); } catch (_) {}
syncButtons(mode);
}
function syncButtons(mode) {
document.querySelectorAll('[data-wirkung]').forEach((btn) => {
const pressed = btn.getAttribute('data-wirkung') === mode;
btn.setAttribute('aria-pressed', pressed ? 'true' : 'false');
});
}
function initWirkung() {
const initial = getStored() || DEFAULT;
applyMode(initial);
document.querySelectorAll('[data-wirkung]').forEach((btn) => {
btn.addEventListener('click', () => {
const mode = btn.getAttribute('data-wirkung');
applyMode(mode);
});
});
}
/* ---------- Mobile Drawer --------------------------------------------- */
function initDrawer() {
const drawer = document.querySelector('[data-mobile-drawer]');
if (!drawer) return;
const openBtns = document.querySelectorAll('[data-drawer-open]');
const closeBtns = document.querySelectorAll('[data-drawer-close]');
function open() {
drawer.classList.add('is-open');
document.body.classList.add('drawer-open');
drawer.setAttribute('aria-hidden', 'false');
const firstLink = drawer.querySelector('a, button');
if (firstLink) firstLink.focus();
}
function close() {
drawer.classList.remove('is-open');
document.body.classList.remove('drawer-open');
drawer.setAttribute('aria-hidden', 'true');
}
openBtns.forEach((b) => b.addEventListener('click', open));
closeBtns.forEach((b) => b.addEventListener('click', close));
drawer.querySelectorAll('a[href]').forEach((a) => {
a.addEventListener('click', close);
});
document.addEventListener('keydown', (e) => {
if (e.key === 'Escape' && drawer.classList.contains('is-open')) {
close();
}
});
}
/* ---------- Scroll Reveal --------------------------------------------- */
function initReveal() {
const items = document.querySelectorAll('[data-reveal]');
if (!items.length) return;
const prefersReduced = window.matchMedia('(prefers-reduced-motion: reduce)').matches;
if (prefersReduced || !('IntersectionObserver' in window)) {
items.forEach((el) => el.classList.add('is-revealed'));
return;
}
const io = new IntersectionObserver((entries) => {
entries.forEach((entry) => {
if (entry.isIntersecting) {
const el = entry.target;
const delay = parseInt(el.getAttribute('data-reveal-delay') || '0', 10);
if (delay > 0) {
setTimeout(() => el.classList.add('is-revealed'), delay);
} else {
el.classList.add('is-revealed');
}
io.unobserve(el);
}
});
}, {
threshold: 0.08,
rootMargin: '0px 0px -5% 0px'
});
items.forEach((el) => io.observe(el));
}
/* ---------- Boot ------------------------------------------------------- */
function boot() {
initWirkung();
initDrawer();
initReveal();
}
if (document.readyState === 'loading') {
document.addEventListener('DOMContentLoaded', boot);
} else {
boot();
}
})();