Merge branch 'mai/hermes/issue-4-impressum-als': Overlay theme-aware + frame-safe (#4)
This commit is contained in:
@@ -11,11 +11,15 @@
|
||||
* data-owner="martinsiebels" — volles Impressum Martin Siebels (separate Person, Osnabrück)
|
||||
* data-owner="msbls" — legacy Alias auf flexsiebels (msbls ist Marke unter flexsiebels-Umbrella)
|
||||
* data-variant="minimal" (default) — Einzeiler im Footer (inline)
|
||||
* data-variant="full" — kleiner Trigger im Footer, voller § 5 TMG-Block im Overlay
|
||||
* data-variant="full" — kleiner Text-Trigger im Footer, voller § 5 TMG-Block im Overlay
|
||||
*
|
||||
* Legacy-Alias: data-style (gleiche Werte wie data-variant).
|
||||
*
|
||||
* Render-Ziel: Element mit id="impressum" falls vorhanden, sonst <footer>, sonst body.
|
||||
*
|
||||
* Theme: das Overlay liest --bg-card / --text / --accent / --border vom Host
|
||||
* (siehe shared/css/variables.css), mit neutralen Dark-Fallbacks für Sites
|
||||
* ohne diese Variablen.
|
||||
*/
|
||||
(function () {
|
||||
const script = document.currentScript;
|
||||
@@ -78,42 +82,35 @@
|
||||
}
|
||||
|
||||
function renderOverlay(html, target) {
|
||||
// Trigger im Footer — klein, dezent, erbt Farben.
|
||||
const trigger = document.createElement('button');
|
||||
trigger.type = 'button';
|
||||
// Trigger: kleiner Text-Link, layout-äquivalent zur inline-minimal-Variante,
|
||||
// damit Footer-Höhe sich nicht ändert.
|
||||
const wrap = document.createElement('div');
|
||||
wrap.className = 'onepager-impressum';
|
||||
wrap.style.cssText = 'text-align:center;font-size:0.75rem;opacity:0.6;padding:12px 0;margin-top:4px;line-height:1.7;';
|
||||
|
||||
const trigger = document.createElement('a');
|
||||
trigger.href = '#impressum';
|
||||
trigger.className = 'onepager-impressum-trigger';
|
||||
trigger.textContent = 'Impressum';
|
||||
trigger.style.cssText = [
|
||||
'display:inline-block',
|
||||
'background:none',
|
||||
'border:none',
|
||||
'padding:12px 8px',
|
||||
'margin-top:4px',
|
||||
'font:inherit',
|
||||
'font-size:0.75rem',
|
||||
'color:inherit',
|
||||
'opacity:0.6',
|
||||
'cursor:pointer',
|
||||
'text-decoration:underline',
|
||||
'text-decoration-thickness:1px',
|
||||
'text-underline-offset:2px',
|
||||
'transition:opacity 0.2s ease',
|
||||
'cursor:pointer',
|
||||
].join(';');
|
||||
trigger.addEventListener('mouseenter', () => { trigger.style.opacity = '1'; });
|
||||
trigger.addEventListener('mouseleave', () => { trigger.style.opacity = '0.6'; });
|
||||
trigger.addEventListener('focus', () => { trigger.style.opacity = '1'; });
|
||||
trigger.addEventListener('blur', () => { trigger.style.opacity = '0.6'; });
|
||||
|
||||
const wrap = document.createElement('div');
|
||||
wrap.className = 'onepager-impressum';
|
||||
wrap.style.cssText = 'text-align:center;padding:8px 0;margin-top:4px;';
|
||||
wrap.appendChild(trigger);
|
||||
target.appendChild(wrap);
|
||||
|
||||
let backdrop = null;
|
||||
let lastFocus = null;
|
||||
let prevBodyOverflow = '';
|
||||
|
||||
trigger.addEventListener('click', open);
|
||||
trigger.addEventListener('click', (e) => {
|
||||
e.preventDefault();
|
||||
open();
|
||||
});
|
||||
|
||||
function open() {
|
||||
if (backdrop) return;
|
||||
@@ -124,11 +121,13 @@
|
||||
backdrop.style.cssText = [
|
||||
'position:fixed',
|
||||
'inset:0',
|
||||
'background:rgba(0,0,0,0.55)',
|
||||
'background:rgba(0,0,0,0.6)',
|
||||
'display:flex',
|
||||
'align-items:center',
|
||||
'justify-content:center',
|
||||
'padding:24px',
|
||||
'padding:16px',
|
||||
'box-sizing:border-box',
|
||||
'overflow:auto',
|
||||
'z-index:99999',
|
||||
'opacity:0',
|
||||
'transition:opacity 0.18s ease',
|
||||
@@ -139,21 +138,26 @@
|
||||
card.setAttribute('role', 'dialog');
|
||||
card.setAttribute('aria-modal', 'true');
|
||||
card.setAttribute('aria-label', 'Impressum');
|
||||
// Theme-aware: nutzt CSS-Variablen vom Host, mit neutralen Dark-Fallbacks.
|
||||
// max-width via min(...) verhindert Frame-Sprengen auf schmalen Viewports.
|
||||
card.style.cssText = [
|
||||
'position:relative',
|
||||
'max-width:420px',
|
||||
'box-sizing:border-box',
|
||||
'max-width:min(420px, calc(100vw - 32px))',
|
||||
'width:100%',
|
||||
'background:#fff',
|
||||
'color:#111',
|
||||
'padding:32px 28px 28px',
|
||||
'border-radius:8px',
|
||||
'box-shadow:0 20px 60px rgba(0,0,0,0.35)',
|
||||
'font-family:system-ui,-apple-system,"Segoe UI",Roboto,sans-serif',
|
||||
'background:var(--bg-card, #16161b)',
|
||||
'color:var(--text, #e8e8ed)',
|
||||
'padding:32px 24px 24px',
|
||||
'border:1px solid var(--border, rgba(255,255,255,0.08))',
|
||||
'border-radius:var(--radius, 8px)',
|
||||
'box-shadow:0 20px 60px rgba(0,0,0,0.5)',
|
||||
'font-family:var(--font-primary, Inter, -apple-system, BlinkMacSystemFont, sans-serif)',
|
||||
'font-size:0.9rem',
|
||||
'line-height:1.55',
|
||||
'line-height:1.6',
|
||||
'overflow-wrap:break-word',
|
||||
'word-wrap:break-word',
|
||||
'transform:translateY(8px)',
|
||||
'transition:transform 0.18s ease',
|
||||
'box-sizing:border-box',
|
||||
].join(';');
|
||||
|
||||
const close = document.createElement('button');
|
||||
@@ -162,32 +166,37 @@
|
||||
close.innerHTML = '×';
|
||||
close.style.cssText = [
|
||||
'position:absolute',
|
||||
'top:6px',
|
||||
'right:10px',
|
||||
'top:4px',
|
||||
'right:8px',
|
||||
'background:none',
|
||||
'border:none',
|
||||
'font-size:1.6rem',
|
||||
'font:inherit',
|
||||
'font-size:1.5rem',
|
||||
'line-height:1',
|
||||
'color:#666',
|
||||
'color:inherit',
|
||||
'opacity:0.5',
|
||||
'cursor:pointer',
|
||||
'padding:6px 10px',
|
||||
'border-radius:4px',
|
||||
'transition:color 0.15s ease',
|
||||
'transition:opacity 0.15s ease',
|
||||
].join(';');
|
||||
close.addEventListener('mouseenter', () => { close.style.color = '#000'; });
|
||||
close.addEventListener('mouseleave', () => { close.style.color = '#666'; });
|
||||
close.addEventListener('mouseenter', () => { close.style.opacity = '1'; });
|
||||
close.addEventListener('mouseleave', () => { close.style.opacity = '0.5'; });
|
||||
close.addEventListener('focus', () => { close.style.opacity = '1'; });
|
||||
close.addEventListener('blur', () => { close.style.opacity = '0.5'; });
|
||||
close.addEventListener('click', dismiss);
|
||||
|
||||
const content = document.createElement('div');
|
||||
content.innerHTML = html;
|
||||
content.style.cssText = 'margin-top:4px;';
|
||||
content.querySelectorAll('a').forEach(a => {
|
||||
a.style.color = '#0057b8';
|
||||
a.style.color = 'var(--accent, #c9a84c)';
|
||||
a.style.textDecoration = 'underline';
|
||||
});
|
||||
content.querySelectorAll('strong').forEach(s => {
|
||||
s.style.display = 'block';
|
||||
s.style.marginBottom = '8px';
|
||||
s.style.marginBottom = '10px';
|
||||
s.style.fontWeight = '600';
|
||||
});
|
||||
|
||||
card.appendChild(close);
|
||||
@@ -195,7 +204,10 @@
|
||||
backdrop.appendChild(card);
|
||||
document.body.appendChild(backdrop);
|
||||
|
||||
// Trigger fade-in nach dem Mounten.
|
||||
// Scroll-Lock auf body, damit Hintergrund nicht mitscrollt.
|
||||
prevBodyOverflow = document.body.style.overflow;
|
||||
document.body.style.overflow = 'hidden';
|
||||
|
||||
requestAnimationFrame(() => {
|
||||
backdrop.style.opacity = '1';
|
||||
card.style.transform = 'translateY(0)';
|
||||
@@ -214,6 +226,7 @@
|
||||
const node = backdrop;
|
||||
backdrop = null;
|
||||
node.style.opacity = '0';
|
||||
document.body.style.overflow = prevBodyOverflow;
|
||||
setTimeout(() => {
|
||||
if (node.parentNode) node.parentNode.removeChild(node);
|
||||
if (lastFocus && typeof lastFocus.focus === 'function') {
|
||||
|
||||
Reference in New Issue
Block a user