diff --git a/static/css/input.css b/static/css/input.css index 6f6d283..65e35ef 100644 --- a/static/css/input.css +++ b/static/css/input.css @@ -30,6 +30,9 @@ --text: #1c1917; /* stone-900 */ --text-secondary: #57534e; /* stone-600 */ --text-muted: #78716c; /* stone-500 */ + + /* Data-viz highlight (RGB triplet for alpha usage in JS) */ + --highlight-rgb: 194, 65, 12; /* orange-700, matches --accent */ } [data-theme="dark"] { @@ -50,6 +53,8 @@ --text: #e7e5e4; --text-secondary: #d6d3d1; --text-muted: #a8a29e; + + --highlight-rgb: 234, 88, 12; /* orange-600, matches --accent */ } /* ── Theme: map raw vars to Tailwind utilities ─────────────────── */ @@ -66,6 +71,7 @@ --color-text-secondary: var(--text-secondary); --color-text-muted: var(--text-muted); --color-border: var(--border); + --color-highlight: rgb(var(--highlight-rgb)); } /* ── Base: default border color ────────────────────────────────── */ diff --git a/static/js/components/world-map.js b/static/js/components/world-map.js index e2b41c1..dbf1532 100644 --- a/static/js/components/world-map.js +++ b/static/js/components/world-map.js @@ -6,7 +6,16 @@ const WORLD_SVG = ` customElements.define("world-map", class extends HTMLElement { static get observedAttributes() { return ["data-countries", "data-max", "data-selected"]; } - connectedCallback() { this._scheduleRender(); } + connectedCallback() { + this._scheduleRender(); + this._themeObserver = new MutationObserver(() => requestAnimationFrame(() => this._recolor())); + this._themeObserver.observe(document.documentElement, { attributes: true, attributeFilter: ['data-theme'] }); + } + + disconnectedCallback() { + this._themeObserver?.disconnect(); + this._themeObserver = null; + } attributeChangedCallback(name) { if (!this.isConnected) return; @@ -64,23 +73,29 @@ customElements.define("world-map", class extends HTMLElement { const counts = this._counts; const max = this._max; + const styles = getComputedStyle(document.documentElement); + const rgb = styles.getPropertyValue('--highlight-rgb').trim() || '185, 28, 28'; + const borderColor = styles.getPropertyValue('--text-muted').trim() || '#9ca3af'; + const surfaceAlt = styles.getPropertyValue('--surface-alt').trim() || '#f5f5f4'; + const borderMuted = styles.getPropertyValue('--border').trim() || '#d6d3d1'; + const applyStyle = (el, fill) => { el.style.fill = fill; - el.style.stroke = "#9ca3af"; + el.style.stroke = borderColor; el.style.strokeWidth = "0.3"; }; const colorFor = (code) => { const count = counts.get(code); if (selected) { - if (code === selected && count) return "rgba(185, 28, 28, 1)"; - return count ? "#d6d3d1" : "#f5f5f4"; + if (code === selected && count) return `rgba(${rgb}, 1)`; + return count ? borderMuted : surfaceAlt; } if (count) { const alpha = (0.15 + 0.85 * (count / max)).toFixed(2); - return `rgba(220, 38, 38, ${alpha})`; + return `rgba(${rgb}, ${alpha})`; } - return "#f5f5f4"; + return surfaceAlt; }; svg.querySelectorAll("path[id], g[id]").forEach((el) => { diff --git a/templates/partials/stats_map.html b/templates/partials/stats_map.html index 1994f7e..01b720f 100644 --- a/templates/partials/stats_map.html +++ b/templates/partials/stats_map.html @@ -31,9 +31,9 @@ {% if !entry.flag_emoji.is_empty() %} {{ entry.flag_emoji }} {% endif %} - {{ entry.country_name }} + {{ entry.country_name }} - {{ entry.count }} + {{ entry.count }} {% else %}
@@ -52,7 +52,5 @@ {{ icons::chevron_right("h-4 w-4") }} - -

{{ geo_stats.total_countries }} {% if geo_stats.total_countries == 1 %}country{% else %}countries{% endif %}

{% endif %}