+
+ {% endif %}
-
-
- {{ generated_at }}
-{% for c in cities %}
-
-
- {{ c.en_name }}
- / {{ c.airport }}
- {{ c.local_time }}
-
+
+
+ {{ generated_at }}
+ {% for c in cities %}
+
+
+ {{ c.en_name }}
+ / {{ c.airport }}
+ {{ c.local_time }}
+
-
- {% match c.current_temp %}
- {% when Some with (t) %}
- {{ "{:.1}"|format(t) }}Β°C
- {% when None %}
- --
- {% endmatch %}
-
+
+ {% match c.current_temp %}
+ {% when Some with (t) %}
+ {{
+ "{:.1}"|format(t) }}Β°C
+ {% when None %}
+ --
+ {% endmatch %}
+
-
-
- Obs
- {% match c.obs_age_min %}
- {% when Some with (m) %}
- {{ m }} min ago
- {% when None %}
- --
- {% endmatch %}
- {{ c.trend.symbol() }}
-
-
-
-{% endfor %}
-
-
Refreshingβ¦
+
Refreshingβ¦
-{% if full_page %}
-
-
+
-
+ updateNotifyIcon();
+
+ // ββ Flash on temp change + notifications ββ
+ (function () {
+ let prev = {};
+ document.body.addEventListener('htmx:afterSwap', function (evt) {
+ if (evt.detail.target.id !== 'card-grid') return;
+ document.querySelectorAll('.card').forEach(function (card) {
+ var name = card.querySelector('.city-name').textContent;
+ var tv = card.querySelector('.temp-value').textContent;
+ var old = prev[name];
+ prev[name] = tv;
+
+ // Flash if changed
+ if (old && old !== tv && tv !== '--') {
+ card.style.transition = 'none';
+ card.style.boxShadow = '0 0 14px rgba(52,211,153,0.40)';
+ requestAnimationFrame(function () {
+ card.style.transition = 'box-shadow 2s ease-out';
+ card.style.boxShadow = '';
+ });
+ }
+
+ // Notification for new high
+ if (card.dataset.newHigh === 'true') {
+ fireNotification(name, tv);
+ }
+ });
+ });
+ })();
+
+