diff --git a/App/sims/klima/game-2d.html b/App/sims/klima/game-2d.html
index e8c1f8c..7f7d3b2 100644
--- a/App/sims/klima/game-2d.html
+++ b/App/sims/klima/game-2d.html
@@ -587,6 +587,23 @@
}
}
+/* Achievement-Tooltip: title-Attribute öffnen sich auf Touch nicht; daher
+ ein eigenes Tap-Popup mit Titel + Beschreibung. */
+.kw-ach-tooltip {
+ position: fixed;
+ z-index: 1500;
+ max-width: 240px;
+ background: var(--ggs-fjord-dark);
+ color: var(--ggs-white);
+ padding: 8px 12px;
+ border-radius: var(--ggs-radius-sm);
+ font-size: 13px;
+ line-height: 1.4;
+ box-shadow: var(--ggs-shadow-md);
+ pointer-events: none;
+ animation: ggs-fade-in 0.15s var(--ggs-ease) both;
+}
+
@keyframes kw-build-slidein {
from { transform: translateX(100%); opacity: 0; }
to { transform: translateX(0); opacity: 1; }
@@ -1728,11 +1745,50 @@ function renderAchievements(force) {
if (!has) classes.push('kw-ach-locked');
el.className = classes.join(' ');
el.title = a.title + (has ? ' — ' + a.desc : ' (noch nicht)');
+ el.dataset.achTitle = a.title;
+ el.dataset.achDesc = has ? a.desc : 'Noch nicht freigeschaltet.';
el.textContent = has ? a.icon : '?';
host.appendChild(el);
});
}
+/* Achievement-Tap-Tooltip — title greift auf Touch nicht. Tap auf eine
+ Badge zeigt einen kleinen schwarzen Tooltip mit Titel + Beschreibung,
+ verschwindet nach 4 s oder beim nächsten Tap außerhalb. */
+let _achTooltip = null;
+let _achTooltipTimer = 0;
+function _hideAchTooltip() {
+ if (_achTooltipTimer) { clearTimeout(_achTooltipTimer); _achTooltipTimer = 0; }
+ if (_achTooltip) { _achTooltip.remove(); _achTooltip = null; }
+}
+document.addEventListener('click', (e) => {
+ if (_achTooltip && !_achTooltip.contains(e.target) && !e.target.closest('.ggs-badge-earned')) {
+ _hideAchTooltip();
+ }
+ const badge = e.target.closest('.ggs-badge-earned');
+ if (!badge) return;
+ const title = badge.dataset.achTitle || badge.title || '';
+ const desc = badge.dataset.achDesc || '';
+ if (!title) return;
+ _hideAchTooltip();
+ const t = document.createElement('div');
+ t.className = 'kw-ach-tooltip';
+ t.innerHTML = '' + title.replace(/[<>&]/g, c => ({'<':'<','>':'>','&':'&'}[c])) + ''
+ + (desc ? '
' + desc.replace(/[<>&]/g, c => ({'<':'<','>':'>','&':'&'}[c])) : '');
+ document.body.appendChild(t);
+ _achTooltip = t;
+ const rect = badge.getBoundingClientRect();
+ const tw = t.offsetWidth;
+ const th = t.offsetHeight;
+ const left = Math.max(8, Math.min(rect.left + rect.width / 2 - tw / 2, window.innerWidth - tw - 8));
+ // Bevorzugt unter der Badge; falls dort kein Platz, nach oben.
+ let top = rect.bottom + 8;
+ if (top + th > window.innerHeight - 8) top = Math.max(8, rect.top - th - 8);
+ t.style.left = left + 'px';
+ t.style.top = top + 'px';
+ _achTooltipTimer = setTimeout(_hideAchTooltip, 4000);
+});
+
/* ============================================================
UI RENDERING
============================================================ */
diff --git a/App/sims/klima/game-3d.html b/App/sims/klima/game-3d.html
index 45b1e49..4d1eed9 100644
--- a/App/sims/klima/game-3d.html
+++ b/App/sims/klima/game-3d.html
@@ -715,6 +715,23 @@
}
}
+/* Achievement-Tooltip: title-Attribute öffnen sich auf Touch nicht; daher
+ ein eigenes Tap-Popup mit Titel + Beschreibung. */
+.kw-ach-tooltip {
+ position: fixed;
+ z-index: 1500;
+ max-width: 240px;
+ background: var(--ggs-fjord-dark);
+ color: var(--ggs-white);
+ padding: 8px 12px;
+ border-radius: var(--ggs-radius-sm);
+ font-size: 13px;
+ line-height: 1.4;
+ box-shadow: var(--ggs-shadow-md);
+ pointer-events: none;
+ animation: ggs-fade-in 0.15s var(--ggs-ease) both;
+}
+
@keyframes kw-build-slidein {
from { transform: translateX(100%); opacity: 0; }
to { transform: translateX(0); opacity: 1; }
@@ -2036,11 +2053,49 @@ function renderAchievements(force) {
if (!has) classes.push('kw-ach-locked');
el.className = classes.join(' ');
el.title = a.title + (has ? ' — ' + a.desc : ' (noch nicht)');
+ el.dataset.achTitle = a.title;
+ el.dataset.achDesc = has ? a.desc : 'Noch nicht freigeschaltet.';
el.textContent = has ? a.icon : '?';
host.appendChild(el);
});
}
+/* Achievement-Tap-Tooltip — title greift auf Touch nicht. Tap auf eine
+ Badge zeigt einen kleinen schwarzen Tooltip mit Titel + Beschreibung,
+ verschwindet nach 4 s oder beim nächsten Tap außerhalb. */
+let _achTooltip = null;
+let _achTooltipTimer = 0;
+function _hideAchTooltip() {
+ if (_achTooltipTimer) { clearTimeout(_achTooltipTimer); _achTooltipTimer = 0; }
+ if (_achTooltip) { _achTooltip.remove(); _achTooltip = null; }
+}
+document.addEventListener('click', (e) => {
+ if (_achTooltip && !_achTooltip.contains(e.target) && !e.target.closest('.ggs-badge-earned')) {
+ _hideAchTooltip();
+ }
+ const badge = e.target.closest('.ggs-badge-earned');
+ if (!badge) return;
+ const title = badge.dataset.achTitle || badge.title || '';
+ const desc = badge.dataset.achDesc || '';
+ if (!title) return;
+ _hideAchTooltip();
+ const t = document.createElement('div');
+ t.className = 'kw-ach-tooltip';
+ t.innerHTML = '' + title.replace(/[<>&]/g, c => ({'<':'<','>':'>','&':'&'}[c])) + ''
+ + (desc ? '
' + desc.replace(/[<>&]/g, c => ({'<':'<','>':'>','&':'&'}[c])) : '');
+ document.body.appendChild(t);
+ _achTooltip = t;
+ const rect = badge.getBoundingClientRect();
+ const tw = t.offsetWidth;
+ const th = t.offsetHeight;
+ const left = Math.max(8, Math.min(rect.left + rect.width / 2 - tw / 2, window.innerWidth - tw - 8));
+ let top = rect.bottom + 8;
+ if (top + th > window.innerHeight - 8) top = Math.max(8, rect.top - th - 8);
+ t.style.left = left + 'px';
+ t.style.top = top + 'px';
+ _achTooltipTimer = setTimeout(_hideAchTooltip, 4000);
+});
+
/* ============================================================
UI RENDERING
============================================================ */