Topic Coverage Heatmap Panel
Decorative heatmap-matrix graphic. Restyle via --lk-* CSS variables.
Install
npx shadcn@latest add https://visual-blocks.akiho.dev/r/panel-topic-heatmap.jsonnpx skills add akifo/landerkitBlocks work with zero setup thanks to baked defaults. Set --lk-accent(and optionally --lk-bg / --lk-radius /--lk-font / --lk-grid) on :rootor any wrapper to restyle.
Source
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 640 400" role="img" aria-label="Heatmap grid graphic — decorative" class="lk-block" data-lk="panel-topic-heatmap" data-lk-contract="1">
<title>Heatmap grid graphic</title>
<desc>Decorative heatmap grid graphic. Illustrative shape only; any implied data is fictional.</desc>
<style>
/* lk-contract v1 — synced from blocks/_contract/header.css */
[data-lk="panel-topic-heatmap"] {
--_accent: var(--lk-accent, #4BE0C3);
--_bg: var(--lk-bg, #0A0F14);
--_radius: var(--lk-radius, 12px);
--_i: oklch(from var(--_bg) clamp(0.14, (0.68 - l) * 999, 0.93) min(c, 0.03) h);
--_i2: color-mix(in oklab, var(--_i) 62%, transparent);
--_i3: color-mix(in oklab, var(--_i) 42%, transparent);
--_hair: color-mix(in oklab, var(--_i) 8%, transparent);
--_g: var(--lk-grid, color-mix(in oklab, var(--_i) 9%, transparent));
--_surf: color-mix(in oklab, var(--_accent) 3%, var(--_bg));
--_soft: color-mix(in oklab, var(--_accent) 24%, transparent);
--_faint: color-mix(in oklab, var(--_accent) 12%, transparent);
--_glow: color-mix(in oklab, var(--_accent) 55%, var(--_bg));
color: var(--_accent);
font-family: var(--lk-font, 'Inter','Neue Haas Grotesk','Helvetica Neue',Arial,sans-serif);
}
/* base ink: text flips with the bg via --_i; dim/semantic classes override (see CONVENTIONS.md) */
[data-lk="panel-topic-heatmap"] text,
[data-lk="panel-topic-heatmap"] tspan { fill: var(--_i); }
/* Layer 3: block-specific — every selector MUST start with [data-lk="panel-topic-heatmap"] */
[data-lk="panel-topic-heatmap"] .card { fill: var(--_surf); stroke: var(--_hair); rx: var(--_radius); }
[data-lk="panel-topic-heatmap"] .grid { fill: none; stroke: var(--_g); stroke-width: 1; }
[data-lk="panel-topic-heatmap"] .hair { stroke: var(--_hair); stroke-width: 1; }
[data-lk="panel-topic-heatmap"] .cell { fill: var(--_accent); rx: calc(var(--_radius) / 3); }
[data-lk="panel-topic-heatmap"] .hot { fill: none; stroke: var(--_accent); stroke-width: 1.5; rx: calc(var(--_radius) / 3); }
[data-lk="panel-topic-heatmap"] .empty { fill: none; stroke: var(--_i3); stroke-width: 1; stroke-dasharray: 3 2; rx: calc(var(--_radius) / 3); }
[data-lk="panel-topic-heatmap"] .ramp { fill: var(--_accent); rx: calc(var(--_radius) / 6); }
/* Hover motion (opt-out): 2 stages. (1) every data cell (fill plus its hot-ring, kept
together) fades and scales in as a diagonal wave, staggered by row+col so it sweeps
top-left to bottom-right. (2) once the wave lands, the hot-ring cells pulse once,
then the dashed no-data cell fades in last. Off for reduced-motion visitors; set the
motion token to 0 to force off. */
[data-lk="panel-topic-heatmap"] .wave { transform-box: fill-box; transform-origin: center; }
[data-lk="panel-topic-heatmap"] .pulse { transform-box: fill-box; transform-origin: center; }
@media (prefers-reduced-motion: no-preference) {
[data-lk="panel-topic-heatmap"]:hover .wave { animation: lk-panel-topic-heatmap-wave calc(var(--lk-motion, 1) * .4s) cubic-bezier(.22,.61,.36,1) both; }
[data-lk="panel-topic-heatmap"]:hover .d1 { animation-delay: calc(var(--lk-motion, 1) * .03s); }
[data-lk="panel-topic-heatmap"]:hover .d2 { animation-delay: calc(var(--lk-motion, 1) * .06s); }
[data-lk="panel-topic-heatmap"]:hover .d3 { animation-delay: calc(var(--lk-motion, 1) * .09s); }
[data-lk="panel-topic-heatmap"]:hover .d4 { animation-delay: calc(var(--lk-motion, 1) * .12s); }
[data-lk="panel-topic-heatmap"]:hover .d5 { animation-delay: calc(var(--lk-motion, 1) * .15s); }
[data-lk="panel-topic-heatmap"]:hover .d6 { animation-delay: calc(var(--lk-motion, 1) * .18s); }
[data-lk="panel-topic-heatmap"]:hover .d7 { animation-delay: calc(var(--lk-motion, 1) * .21s); }
[data-lk="panel-topic-heatmap"]:hover .d8 { animation-delay: calc(var(--lk-motion, 1) * .24s); }
[data-lk="panel-topic-heatmap"]:hover .pulse { animation: lk-panel-topic-heatmap-pulse calc(var(--lk-motion, 1) * .35s) ease-out both; animation-delay: calc(var(--lk-motion, 1) * .64s); }
[data-lk="panel-topic-heatmap"]:hover .fade { animation: lk-panel-topic-heatmap-fade calc(var(--lk-motion, 1) * .35s) ease-out both; animation-delay: calc(var(--lk-motion, 1) * .95s); }
}
@keyframes lk-panel-topic-heatmap-wave { from { opacity: 0; transform: scale(.6); } to { opacity: 1; transform: scale(1); } }
@keyframes lk-panel-topic-heatmap-pulse { 0% { transform: scale(1); } 50% { transform: scale(1.3); } 100% { transform: scale(1); } }
@keyframes lk-panel-topic-heatmap-fade { from { opacity: 0; } to { opacity: 1; } }
</style>
<rect class="card" x=".5" y=".5" width="639" height="399" rx="12" fill="#0E141B" stroke="#1A2128"/>
<!-- réseau crosses: dead corners of the margin band, on the grid token (silenced when lk-grid is transparent) -->
<path class="grid" d="M27 25h6M30 22v6" fill="none" stroke="#1C262C" stroke-width="1"/>
<path class="grid" d="M607 391h6M610 388v6" fill="none" stroke="#1C262C" stroke-width="1"/>
<!-- legend ramp: 5-step opacity swatches, single accent hue, centered above the grid -->
<rect class="ramp" x="277" y="20" width="14" height="10" rx="2" fill="#4BE0C3" opacity="0.08"/>
<rect class="ramp" x="295" y="20" width="14" height="10" rx="2" fill="#4BE0C3" opacity="0.2"/>
<rect class="ramp" x="313" y="20" width="14" height="10" rx="2" fill="#4BE0C3" opacity="0.36"/>
<rect class="ramp" x="331" y="20" width="14" height="10" rx="2" fill="#4BE0C3" opacity="0.56"/>
<rect class="ramp" x="349" y="20" width="14" height="10" rx="2" fill="#4BE0C3" opacity="0.8"/>
<line class="hair" x1="20" y1="50" x2="620" y2="50" stroke="#1A2128" stroke-width="1"/>
<!-- 6x4 matrix: single-hue accent cells, opacity steps encode value; grid expanded edge to edge -->
<!-- row 1 -->
<g class="wave"><rect class="cell" x="20" y="62" width="142.5" height="43.8" rx="4" fill="#4BE0C3" opacity="0.56"/></g>
<g class="wave d1"><rect class="cell" x="172.5" y="62" width="142.5" height="43.8" rx="4" fill="#4BE0C3" opacity="0.56"/></g>
<g class="wave d2"><rect class="cell" x="325" y="62" width="142.5" height="43.8" rx="4" fill="#4BE0C3" opacity="0.2"/></g>
<g class="wave d3"><rect class="cell" x="477.5" y="62" width="142.5" height="43.8" rx="4" fill="#4BE0C3" opacity="0.08"/></g>
<!-- row 2 (hot cell in column 2) -->
<g class="wave d1"><rect class="cell" x="20" y="116.8" width="142.5" height="43.8" rx="4" fill="#4BE0C3" opacity="0.56"/></g>
<g class="wave d2">
<rect class="cell" x="172.5" y="116.8" width="142.5" height="43.8" rx="4" fill="#4BE0C3" opacity="0.8"/>
<rect class="hot pulse" x="172.5" y="116.8" width="142.5" height="43.8" rx="4" fill="none" stroke="#4BE0C3" stroke-width="1.5"/>
</g>
<g class="wave d3"><rect class="cell" x="325" y="116.8" width="142.5" height="43.8" rx="4" fill="#4BE0C3" opacity="0.36"/></g>
<g class="wave d4"><rect class="cell" x="477.5" y="116.8" width="142.5" height="43.8" rx="4" fill="#4BE0C3" opacity="0.2"/></g>
<!-- row 3 -->
<g class="wave d2"><rect class="cell" x="20" y="171.6" width="142.5" height="43.8" rx="4" fill="#4BE0C3" opacity="0.56"/></g>
<g class="wave d3"><rect class="cell" x="172.5" y="171.6" width="142.5" height="43.8" rx="4" fill="#4BE0C3" opacity="0.36"/></g>
<g class="wave d4"><rect class="cell" x="325" y="171.6" width="142.5" height="43.8" rx="4" fill="#4BE0C3" opacity="0.2"/></g>
<g class="wave d5"><rect class="cell" x="477.5" y="171.6" width="142.5" height="43.8" rx="4" fill="#4BE0C3" opacity="0.08"/></g>
<!-- row 4 (column 4 has no data — dashed empty cell) -->
<g class="wave d3"><rect class="cell" x="20" y="226.4" width="142.5" height="43.8" rx="4" fill="#4BE0C3" opacity="0.2"/></g>
<g class="wave d4"><rect class="cell" x="172.5" y="226.4" width="142.5" height="43.8" rx="4" fill="#4BE0C3" opacity="0.36"/></g>
<g class="wave d5"><rect class="cell" x="325" y="226.4" width="142.5" height="43.8" rx="4" fill="#4BE0C3" opacity="0.08"/></g>
<rect class="empty fade" x="477.5" y="226.4" width="142.5" height="43.8" rx="4" fill="none" stroke="#E6EDEE6B" stroke-width="1" stroke-dasharray="3 2"/>
<!-- row 5 (hottest row — column 1 carries the top hot-ring cell) -->
<g class="wave d4">
<rect class="cell" x="20" y="281.2" width="142.5" height="43.8" rx="4" fill="#4BE0C3" opacity="0.8"/>
<rect class="hot pulse" x="20" y="281.2" width="142.5" height="43.8" rx="4" fill="none" stroke="#4BE0C3" stroke-width="1.5"/>
</g>
<g class="wave d5"><rect class="cell" x="172.5" y="281.2" width="142.5" height="43.8" rx="4" fill="#4BE0C3" opacity="0.56"/></g>
<g class="wave d6"><rect class="cell" x="325" y="281.2" width="142.5" height="43.8" rx="4" fill="#4BE0C3" opacity="0.36"/></g>
<g class="wave d7"><rect class="cell" x="477.5" y="281.2" width="142.5" height="43.8" rx="4" fill="#4BE0C3" opacity="0.2"/></g>
<!-- row 6 (weakest row overall) -->
<g class="wave d5"><rect class="cell" x="20" y="336" width="142.5" height="43.8" rx="4" fill="#4BE0C3" opacity="0.36"/></g>
<g class="wave d6"><rect class="cell" x="172.5" y="336" width="142.5" height="43.8" rx="4" fill="#4BE0C3" opacity="0.2"/></g>
<g class="wave d7"><rect class="cell" x="325" y="336" width="142.5" height="43.8" rx="4" fill="#4BE0C3" opacity="0.08"/></g>
<g class="wave d8"><rect class="cell" x="477.5" y="336" width="142.5" height="43.8" rx="4" fill="#4BE0C3" opacity="0.08"/></g>
</svg>
/* GENERATED FROM blocks/ (catalog.json + *.svg + _contract/) — DO NOT EDIT. Run `pnpm generate`. */
import type { HTMLAttributes } from 'react';
const svg = "<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 640 400\" role=\"img\" aria-label=\"Heatmap grid graphic — decorative\" class=\"lk-block\" data-lk=\"panel-topic-heatmap\" data-lk-contract=\"1\">\n <title>Heatmap grid graphic</title>\n <desc>Decorative heatmap grid graphic. Illustrative shape only; any implied data is fictional.</desc>\n <style>\n /* lk-contract v1 — synced from blocks/_contract/header.css */\n [data-lk=\"panel-topic-heatmap\"] {\n --_accent: var(--lk-accent, #4BE0C3);\n --_bg: var(--lk-bg, #0A0F14);\n --_radius: var(--lk-radius, 12px);\n --_i: oklch(from var(--_bg) clamp(0.14, (0.68 - l) * 999, 0.93) min(c, 0.03) h);\n --_i2: color-mix(in oklab, var(--_i) 62%, transparent);\n --_i3: color-mix(in oklab, var(--_i) 42%, transparent);\n --_hair: color-mix(in oklab, var(--_i) 8%, transparent);\n --_g: var(--lk-grid, color-mix(in oklab, var(--_i) 9%, transparent));\n --_surf: color-mix(in oklab, var(--_accent) 3%, var(--_bg));\n --_soft: color-mix(in oklab, var(--_accent) 24%, transparent);\n --_faint: color-mix(in oklab, var(--_accent) 12%, transparent);\n --_glow: color-mix(in oklab, var(--_accent) 55%, var(--_bg));\n color: var(--_accent);\n font-family: var(--lk-font, 'Inter','Neue Haas Grotesk','Helvetica Neue',Arial,sans-serif);\n }\n /* base ink: text flips with the bg via --_i; dim/semantic classes override (see CONVENTIONS.md) */\n [data-lk=\"panel-topic-heatmap\"] text,\n [data-lk=\"panel-topic-heatmap\"] tspan { fill: var(--_i); }\n\n\n /* Layer 3: block-specific — every selector MUST start with [data-lk=\"panel-topic-heatmap\"] */\n [data-lk=\"panel-topic-heatmap\"] .card { fill: var(--_surf); stroke: var(--_hair); rx: var(--_radius); }\n [data-lk=\"panel-topic-heatmap\"] .grid { fill: none; stroke: var(--_g); stroke-width: 1; }\n [data-lk=\"panel-topic-heatmap\"] .hair { stroke: var(--_hair); stroke-width: 1; }\n [data-lk=\"panel-topic-heatmap\"] .cell { fill: var(--_accent); rx: calc(var(--_radius) / 3); }\n [data-lk=\"panel-topic-heatmap\"] .hot { fill: none; stroke: var(--_accent); stroke-width: 1.5; rx: calc(var(--_radius) / 3); }\n [data-lk=\"panel-topic-heatmap\"] .empty { fill: none; stroke: var(--_i3); stroke-width: 1; stroke-dasharray: 3 2; rx: calc(var(--_radius) / 3); }\n [data-lk=\"panel-topic-heatmap\"] .ramp { fill: var(--_accent); rx: calc(var(--_radius) / 6); }\n\n /* Hover motion (opt-out): 2 stages. (1) every data cell (fill plus its hot-ring, kept\n together) fades and scales in as a diagonal wave, staggered by row+col so it sweeps\n top-left to bottom-right. (2) once the wave lands, the hot-ring cells pulse once,\n then the dashed no-data cell fades in last. Off for reduced-motion visitors; set the\n motion token to 0 to force off. */\n [data-lk=\"panel-topic-heatmap\"] .wave { transform-box: fill-box; transform-origin: center; }\n [data-lk=\"panel-topic-heatmap\"] .pulse { transform-box: fill-box; transform-origin: center; }\n @media (prefers-reduced-motion: no-preference) {\n [data-lk=\"panel-topic-heatmap\"]:hover .wave { animation: lk-panel-topic-heatmap-wave calc(var(--lk-motion, 1) * .4s) cubic-bezier(.22,.61,.36,1) both; }\n [data-lk=\"panel-topic-heatmap\"]:hover .d1 { animation-delay: calc(var(--lk-motion, 1) * .03s); }\n [data-lk=\"panel-topic-heatmap\"]:hover .d2 { animation-delay: calc(var(--lk-motion, 1) * .06s); }\n [data-lk=\"panel-topic-heatmap\"]:hover .d3 { animation-delay: calc(var(--lk-motion, 1) * .09s); }\n [data-lk=\"panel-topic-heatmap\"]:hover .d4 { animation-delay: calc(var(--lk-motion, 1) * .12s); }\n [data-lk=\"panel-topic-heatmap\"]:hover .d5 { animation-delay: calc(var(--lk-motion, 1) * .15s); }\n [data-lk=\"panel-topic-heatmap\"]:hover .d6 { animation-delay: calc(var(--lk-motion, 1) * .18s); }\n [data-lk=\"panel-topic-heatmap\"]:hover .d7 { animation-delay: calc(var(--lk-motion, 1) * .21s); }\n [data-lk=\"panel-topic-heatmap\"]:hover .d8 { animation-delay: calc(var(--lk-motion, 1) * .24s); }\n [data-lk=\"panel-topic-heatmap\"]:hover .pulse { animation: lk-panel-topic-heatmap-pulse calc(var(--lk-motion, 1) * .35s) ease-out both; animation-delay: calc(var(--lk-motion, 1) * .64s); }\n [data-lk=\"panel-topic-heatmap\"]:hover .fade { animation: lk-panel-topic-heatmap-fade calc(var(--lk-motion, 1) * .35s) ease-out both; animation-delay: calc(var(--lk-motion, 1) * .95s); }\n }\n @keyframes lk-panel-topic-heatmap-wave { from { opacity: 0; transform: scale(.6); } to { opacity: 1; transform: scale(1); } }\n @keyframes lk-panel-topic-heatmap-pulse { 0% { transform: scale(1); } 50% { transform: scale(1.3); } 100% { transform: scale(1); } }\n @keyframes lk-panel-topic-heatmap-fade { from { opacity: 0; } to { opacity: 1; } }\n </style>\n <rect class=\"card\" x=\".5\" y=\".5\" width=\"639\" height=\"399\" rx=\"12\" fill=\"#0E141B\" stroke=\"#1A2128\"/>\n\n <!-- réseau crosses: dead corners of the margin band, on the grid token (silenced when lk-grid is transparent) -->\n <path class=\"grid\" d=\"M27 25h6M30 22v6\" fill=\"none\" stroke=\"#1C262C\" stroke-width=\"1\"/>\n <path class=\"grid\" d=\"M607 391h6M610 388v6\" fill=\"none\" stroke=\"#1C262C\" stroke-width=\"1\"/>\n\n <!-- legend ramp: 5-step opacity swatches, single accent hue, centered above the grid -->\n <rect class=\"ramp\" x=\"277\" y=\"20\" width=\"14\" height=\"10\" rx=\"2\" fill=\"#4BE0C3\" opacity=\"0.08\"/>\n <rect class=\"ramp\" x=\"295\" y=\"20\" width=\"14\" height=\"10\" rx=\"2\" fill=\"#4BE0C3\" opacity=\"0.2\"/>\n <rect class=\"ramp\" x=\"313\" y=\"20\" width=\"14\" height=\"10\" rx=\"2\" fill=\"#4BE0C3\" opacity=\"0.36\"/>\n <rect class=\"ramp\" x=\"331\" y=\"20\" width=\"14\" height=\"10\" rx=\"2\" fill=\"#4BE0C3\" opacity=\"0.56\"/>\n <rect class=\"ramp\" x=\"349\" y=\"20\" width=\"14\" height=\"10\" rx=\"2\" fill=\"#4BE0C3\" opacity=\"0.8\"/>\n <line class=\"hair\" x1=\"20\" y1=\"50\" x2=\"620\" y2=\"50\" stroke=\"#1A2128\" stroke-width=\"1\"/>\n\n <!-- 6x4 matrix: single-hue accent cells, opacity steps encode value; grid expanded edge to edge -->\n <!-- row 1 -->\n <g class=\"wave\"><rect class=\"cell\" x=\"20\" y=\"62\" width=\"142.5\" height=\"43.8\" rx=\"4\" fill=\"#4BE0C3\" opacity=\"0.56\"/></g>\n <g class=\"wave d1\"><rect class=\"cell\" x=\"172.5\" y=\"62\" width=\"142.5\" height=\"43.8\" rx=\"4\" fill=\"#4BE0C3\" opacity=\"0.56\"/></g>\n <g class=\"wave d2\"><rect class=\"cell\" x=\"325\" y=\"62\" width=\"142.5\" height=\"43.8\" rx=\"4\" fill=\"#4BE0C3\" opacity=\"0.2\"/></g>\n <g class=\"wave d3\"><rect class=\"cell\" x=\"477.5\" y=\"62\" width=\"142.5\" height=\"43.8\" rx=\"4\" fill=\"#4BE0C3\" opacity=\"0.08\"/></g>\n\n <!-- row 2 (hot cell in column 2) -->\n <g class=\"wave d1\"><rect class=\"cell\" x=\"20\" y=\"116.8\" width=\"142.5\" height=\"43.8\" rx=\"4\" fill=\"#4BE0C3\" opacity=\"0.56\"/></g>\n <g class=\"wave d2\">\n <rect class=\"cell\" x=\"172.5\" y=\"116.8\" width=\"142.5\" height=\"43.8\" rx=\"4\" fill=\"#4BE0C3\" opacity=\"0.8\"/>\n <rect class=\"hot pulse\" x=\"172.5\" y=\"116.8\" width=\"142.5\" height=\"43.8\" rx=\"4\" fill=\"none\" stroke=\"#4BE0C3\" stroke-width=\"1.5\"/>\n </g>\n <g class=\"wave d3\"><rect class=\"cell\" x=\"325\" y=\"116.8\" width=\"142.5\" height=\"43.8\" rx=\"4\" fill=\"#4BE0C3\" opacity=\"0.36\"/></g>\n <g class=\"wave d4\"><rect class=\"cell\" x=\"477.5\" y=\"116.8\" width=\"142.5\" height=\"43.8\" rx=\"4\" fill=\"#4BE0C3\" opacity=\"0.2\"/></g>\n\n <!-- row 3 -->\n <g class=\"wave d2\"><rect class=\"cell\" x=\"20\" y=\"171.6\" width=\"142.5\" height=\"43.8\" rx=\"4\" fill=\"#4BE0C3\" opacity=\"0.56\"/></g>\n <g class=\"wave d3\"><rect class=\"cell\" x=\"172.5\" y=\"171.6\" width=\"142.5\" height=\"43.8\" rx=\"4\" fill=\"#4BE0C3\" opacity=\"0.36\"/></g>\n <g class=\"wave d4\"><rect class=\"cell\" x=\"325\" y=\"171.6\" width=\"142.5\" height=\"43.8\" rx=\"4\" fill=\"#4BE0C3\" opacity=\"0.2\"/></g>\n <g class=\"wave d5\"><rect class=\"cell\" x=\"477.5\" y=\"171.6\" width=\"142.5\" height=\"43.8\" rx=\"4\" fill=\"#4BE0C3\" opacity=\"0.08\"/></g>\n\n <!-- row 4 (column 4 has no data — dashed empty cell) -->\n <g class=\"wave d3\"><rect class=\"cell\" x=\"20\" y=\"226.4\" width=\"142.5\" height=\"43.8\" rx=\"4\" fill=\"#4BE0C3\" opacity=\"0.2\"/></g>\n <g class=\"wave d4\"><rect class=\"cell\" x=\"172.5\" y=\"226.4\" width=\"142.5\" height=\"43.8\" rx=\"4\" fill=\"#4BE0C3\" opacity=\"0.36\"/></g>\n <g class=\"wave d5\"><rect class=\"cell\" x=\"325\" y=\"226.4\" width=\"142.5\" height=\"43.8\" rx=\"4\" fill=\"#4BE0C3\" opacity=\"0.08\"/></g>\n <rect class=\"empty fade\" x=\"477.5\" y=\"226.4\" width=\"142.5\" height=\"43.8\" rx=\"4\" fill=\"none\" stroke=\"#E6EDEE6B\" stroke-width=\"1\" stroke-dasharray=\"3 2\"/>\n\n <!-- row 5 (hottest row — column 1 carries the top hot-ring cell) -->\n <g class=\"wave d4\">\n <rect class=\"cell\" x=\"20\" y=\"281.2\" width=\"142.5\" height=\"43.8\" rx=\"4\" fill=\"#4BE0C3\" opacity=\"0.8\"/>\n <rect class=\"hot pulse\" x=\"20\" y=\"281.2\" width=\"142.5\" height=\"43.8\" rx=\"4\" fill=\"none\" stroke=\"#4BE0C3\" stroke-width=\"1.5\"/>\n </g>\n <g class=\"wave d5\"><rect class=\"cell\" x=\"172.5\" y=\"281.2\" width=\"142.5\" height=\"43.8\" rx=\"4\" fill=\"#4BE0C3\" opacity=\"0.56\"/></g>\n <g class=\"wave d6\"><rect class=\"cell\" x=\"325\" y=\"281.2\" width=\"142.5\" height=\"43.8\" rx=\"4\" fill=\"#4BE0C3\" opacity=\"0.36\"/></g>\n <g class=\"wave d7\"><rect class=\"cell\" x=\"477.5\" y=\"281.2\" width=\"142.5\" height=\"43.8\" rx=\"4\" fill=\"#4BE0C3\" opacity=\"0.2\"/></g>\n\n <!-- row 6 (weakest row overall) -->\n <g class=\"wave d5\"><rect class=\"cell\" x=\"20\" y=\"336\" width=\"142.5\" height=\"43.8\" rx=\"4\" fill=\"#4BE0C3\" opacity=\"0.36\"/></g>\n <g class=\"wave d6\"><rect class=\"cell\" x=\"172.5\" y=\"336\" width=\"142.5\" height=\"43.8\" rx=\"4\" fill=\"#4BE0C3\" opacity=\"0.2\"/></g>\n <g class=\"wave d7\"><rect class=\"cell\" x=\"325\" y=\"336\" width=\"142.5\" height=\"43.8\" rx=\"4\" fill=\"#4BE0C3\" opacity=\"0.08\"/></g>\n <g class=\"wave d8\"><rect class=\"cell\" x=\"477.5\" y=\"336\" width=\"142.5\" height=\"43.8\" rx=\"4\" fill=\"#4BE0C3\" opacity=\"0.08\"/></g>\n</svg>\n";
export function TopicCoverageHeatmapPanel(props: HTMLAttributes<HTMLDivElement>) {
return <div {...props} dangerouslySetInnerHTML={{ __html: svg }} />;
}
export default TopicCoverageHeatmapPanel;
<!-- GENERATED FROM blocks/ (catalog.json + *.svg + _contract/) — DO NOT EDIT. Run `pnpm generate`. -->
<template>
<div v-html="svg" />
</template>
<script setup lang="ts">
const svg = "<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 640 400\" role=\"img\" aria-label=\"Heatmap grid graphic — decorative\" class=\"lk-block\" data-lk=\"panel-topic-heatmap\" data-lk-contract=\"1\">\n <title>Heatmap grid graphic</title>\n <desc>Decorative heatmap grid graphic. Illustrative shape only; any implied data is fictional.</desc>\n <style>\n /* lk-contract v1 — synced from blocks/_contract/header.css */\n [data-lk=\"panel-topic-heatmap\"] {\n --_accent: var(--lk-accent, #4BE0C3);\n --_bg: var(--lk-bg, #0A0F14);\n --_radius: var(--lk-radius, 12px);\n --_i: oklch(from var(--_bg) clamp(0.14, (0.68 - l) * 999, 0.93) min(c, 0.03) h);\n --_i2: color-mix(in oklab, var(--_i) 62%, transparent);\n --_i3: color-mix(in oklab, var(--_i) 42%, transparent);\n --_hair: color-mix(in oklab, var(--_i) 8%, transparent);\n --_g: var(--lk-grid, color-mix(in oklab, var(--_i) 9%, transparent));\n --_surf: color-mix(in oklab, var(--_accent) 3%, var(--_bg));\n --_soft: color-mix(in oklab, var(--_accent) 24%, transparent);\n --_faint: color-mix(in oklab, var(--_accent) 12%, transparent);\n --_glow: color-mix(in oklab, var(--_accent) 55%, var(--_bg));\n color: var(--_accent);\n font-family: var(--lk-font, 'Inter','Neue Haas Grotesk','Helvetica Neue',Arial,sans-serif);\n }\n /* base ink: text flips with the bg via --_i; dim/semantic classes override (see CONVENTIONS.md) */\n [data-lk=\"panel-topic-heatmap\"] text,\n [data-lk=\"panel-topic-heatmap\"] tspan { fill: var(--_i); }\n\n\n /* Layer 3: block-specific — every selector MUST start with [data-lk=\"panel-topic-heatmap\"] */\n [data-lk=\"panel-topic-heatmap\"] .card { fill: var(--_surf); stroke: var(--_hair); rx: var(--_radius); }\n [data-lk=\"panel-topic-heatmap\"] .grid { fill: none; stroke: var(--_g); stroke-width: 1; }\n [data-lk=\"panel-topic-heatmap\"] .hair { stroke: var(--_hair); stroke-width: 1; }\n [data-lk=\"panel-topic-heatmap\"] .cell { fill: var(--_accent); rx: calc(var(--_radius) / 3); }\n [data-lk=\"panel-topic-heatmap\"] .hot { fill: none; stroke: var(--_accent); stroke-width: 1.5; rx: calc(var(--_radius) / 3); }\n [data-lk=\"panel-topic-heatmap\"] .empty { fill: none; stroke: var(--_i3); stroke-width: 1; stroke-dasharray: 3 2; rx: calc(var(--_radius) / 3); }\n [data-lk=\"panel-topic-heatmap\"] .ramp { fill: var(--_accent); rx: calc(var(--_radius) / 6); }\n\n /* Hover motion (opt-out): 2 stages. (1) every data cell (fill plus its hot-ring, kept\n together) fades and scales in as a diagonal wave, staggered by row+col so it sweeps\n top-left to bottom-right. (2) once the wave lands, the hot-ring cells pulse once,\n then the dashed no-data cell fades in last. Off for reduced-motion visitors; set the\n motion token to 0 to force off. */\n [data-lk=\"panel-topic-heatmap\"] .wave { transform-box: fill-box; transform-origin: center; }\n [data-lk=\"panel-topic-heatmap\"] .pulse { transform-box: fill-box; transform-origin: center; }\n @media (prefers-reduced-motion: no-preference) {\n [data-lk=\"panel-topic-heatmap\"]:hover .wave { animation: lk-panel-topic-heatmap-wave calc(var(--lk-motion, 1) * .4s) cubic-bezier(.22,.61,.36,1) both; }\n [data-lk=\"panel-topic-heatmap\"]:hover .d1 { animation-delay: calc(var(--lk-motion, 1) * .03s); }\n [data-lk=\"panel-topic-heatmap\"]:hover .d2 { animation-delay: calc(var(--lk-motion, 1) * .06s); }\n [data-lk=\"panel-topic-heatmap\"]:hover .d3 { animation-delay: calc(var(--lk-motion, 1) * .09s); }\n [data-lk=\"panel-topic-heatmap\"]:hover .d4 { animation-delay: calc(var(--lk-motion, 1) * .12s); }\n [data-lk=\"panel-topic-heatmap\"]:hover .d5 { animation-delay: calc(var(--lk-motion, 1) * .15s); }\n [data-lk=\"panel-topic-heatmap\"]:hover .d6 { animation-delay: calc(var(--lk-motion, 1) * .18s); }\n [data-lk=\"panel-topic-heatmap\"]:hover .d7 { animation-delay: calc(var(--lk-motion, 1) * .21s); }\n [data-lk=\"panel-topic-heatmap\"]:hover .d8 { animation-delay: calc(var(--lk-motion, 1) * .24s); }\n [data-lk=\"panel-topic-heatmap\"]:hover .pulse { animation: lk-panel-topic-heatmap-pulse calc(var(--lk-motion, 1) * .35s) ease-out both; animation-delay: calc(var(--lk-motion, 1) * .64s); }\n [data-lk=\"panel-topic-heatmap\"]:hover .fade { animation: lk-panel-topic-heatmap-fade calc(var(--lk-motion, 1) * .35s) ease-out both; animation-delay: calc(var(--lk-motion, 1) * .95s); }\n }\n @keyframes lk-panel-topic-heatmap-wave { from { opacity: 0; transform: scale(.6); } to { opacity: 1; transform: scale(1); } }\n @keyframes lk-panel-topic-heatmap-pulse { 0% { transform: scale(1); } 50% { transform: scale(1.3); } 100% { transform: scale(1); } }\n @keyframes lk-panel-topic-heatmap-fade { from { opacity: 0; } to { opacity: 1; } }\n </style>\n <rect class=\"card\" x=\".5\" y=\".5\" width=\"639\" height=\"399\" rx=\"12\" fill=\"#0E141B\" stroke=\"#1A2128\"/>\n\n <!-- réseau crosses: dead corners of the margin band, on the grid token (silenced when lk-grid is transparent) -->\n <path class=\"grid\" d=\"M27 25h6M30 22v6\" fill=\"none\" stroke=\"#1C262C\" stroke-width=\"1\"/>\n <path class=\"grid\" d=\"M607 391h6M610 388v6\" fill=\"none\" stroke=\"#1C262C\" stroke-width=\"1\"/>\n\n <!-- legend ramp: 5-step opacity swatches, single accent hue, centered above the grid -->\n <rect class=\"ramp\" x=\"277\" y=\"20\" width=\"14\" height=\"10\" rx=\"2\" fill=\"#4BE0C3\" opacity=\"0.08\"/>\n <rect class=\"ramp\" x=\"295\" y=\"20\" width=\"14\" height=\"10\" rx=\"2\" fill=\"#4BE0C3\" opacity=\"0.2\"/>\n <rect class=\"ramp\" x=\"313\" y=\"20\" width=\"14\" height=\"10\" rx=\"2\" fill=\"#4BE0C3\" opacity=\"0.36\"/>\n <rect class=\"ramp\" x=\"331\" y=\"20\" width=\"14\" height=\"10\" rx=\"2\" fill=\"#4BE0C3\" opacity=\"0.56\"/>\n <rect class=\"ramp\" x=\"349\" y=\"20\" width=\"14\" height=\"10\" rx=\"2\" fill=\"#4BE0C3\" opacity=\"0.8\"/>\n <line class=\"hair\" x1=\"20\" y1=\"50\" x2=\"620\" y2=\"50\" stroke=\"#1A2128\" stroke-width=\"1\"/>\n\n <!-- 6x4 matrix: single-hue accent cells, opacity steps encode value; grid expanded edge to edge -->\n <!-- row 1 -->\n <g class=\"wave\"><rect class=\"cell\" x=\"20\" y=\"62\" width=\"142.5\" height=\"43.8\" rx=\"4\" fill=\"#4BE0C3\" opacity=\"0.56\"/></g>\n <g class=\"wave d1\"><rect class=\"cell\" x=\"172.5\" y=\"62\" width=\"142.5\" height=\"43.8\" rx=\"4\" fill=\"#4BE0C3\" opacity=\"0.56\"/></g>\n <g class=\"wave d2\"><rect class=\"cell\" x=\"325\" y=\"62\" width=\"142.5\" height=\"43.8\" rx=\"4\" fill=\"#4BE0C3\" opacity=\"0.2\"/></g>\n <g class=\"wave d3\"><rect class=\"cell\" x=\"477.5\" y=\"62\" width=\"142.5\" height=\"43.8\" rx=\"4\" fill=\"#4BE0C3\" opacity=\"0.08\"/></g>\n\n <!-- row 2 (hot cell in column 2) -->\n <g class=\"wave d1\"><rect class=\"cell\" x=\"20\" y=\"116.8\" width=\"142.5\" height=\"43.8\" rx=\"4\" fill=\"#4BE0C3\" opacity=\"0.56\"/></g>\n <g class=\"wave d2\">\n <rect class=\"cell\" x=\"172.5\" y=\"116.8\" width=\"142.5\" height=\"43.8\" rx=\"4\" fill=\"#4BE0C3\" opacity=\"0.8\"/>\n <rect class=\"hot pulse\" x=\"172.5\" y=\"116.8\" width=\"142.5\" height=\"43.8\" rx=\"4\" fill=\"none\" stroke=\"#4BE0C3\" stroke-width=\"1.5\"/>\n </g>\n <g class=\"wave d3\"><rect class=\"cell\" x=\"325\" y=\"116.8\" width=\"142.5\" height=\"43.8\" rx=\"4\" fill=\"#4BE0C3\" opacity=\"0.36\"/></g>\n <g class=\"wave d4\"><rect class=\"cell\" x=\"477.5\" y=\"116.8\" width=\"142.5\" height=\"43.8\" rx=\"4\" fill=\"#4BE0C3\" opacity=\"0.2\"/></g>\n\n <!-- row 3 -->\n <g class=\"wave d2\"><rect class=\"cell\" x=\"20\" y=\"171.6\" width=\"142.5\" height=\"43.8\" rx=\"4\" fill=\"#4BE0C3\" opacity=\"0.56\"/></g>\n <g class=\"wave d3\"><rect class=\"cell\" x=\"172.5\" y=\"171.6\" width=\"142.5\" height=\"43.8\" rx=\"4\" fill=\"#4BE0C3\" opacity=\"0.36\"/></g>\n <g class=\"wave d4\"><rect class=\"cell\" x=\"325\" y=\"171.6\" width=\"142.5\" height=\"43.8\" rx=\"4\" fill=\"#4BE0C3\" opacity=\"0.2\"/></g>\n <g class=\"wave d5\"><rect class=\"cell\" x=\"477.5\" y=\"171.6\" width=\"142.5\" height=\"43.8\" rx=\"4\" fill=\"#4BE0C3\" opacity=\"0.08\"/></g>\n\n <!-- row 4 (column 4 has no data — dashed empty cell) -->\n <g class=\"wave d3\"><rect class=\"cell\" x=\"20\" y=\"226.4\" width=\"142.5\" height=\"43.8\" rx=\"4\" fill=\"#4BE0C3\" opacity=\"0.2\"/></g>\n <g class=\"wave d4\"><rect class=\"cell\" x=\"172.5\" y=\"226.4\" width=\"142.5\" height=\"43.8\" rx=\"4\" fill=\"#4BE0C3\" opacity=\"0.36\"/></g>\n <g class=\"wave d5\"><rect class=\"cell\" x=\"325\" y=\"226.4\" width=\"142.5\" height=\"43.8\" rx=\"4\" fill=\"#4BE0C3\" opacity=\"0.08\"/></g>\n <rect class=\"empty fade\" x=\"477.5\" y=\"226.4\" width=\"142.5\" height=\"43.8\" rx=\"4\" fill=\"none\" stroke=\"#E6EDEE6B\" stroke-width=\"1\" stroke-dasharray=\"3 2\"/>\n\n <!-- row 5 (hottest row — column 1 carries the top hot-ring cell) -->\n <g class=\"wave d4\">\n <rect class=\"cell\" x=\"20\" y=\"281.2\" width=\"142.5\" height=\"43.8\" rx=\"4\" fill=\"#4BE0C3\" opacity=\"0.8\"/>\n <rect class=\"hot pulse\" x=\"20\" y=\"281.2\" width=\"142.5\" height=\"43.8\" rx=\"4\" fill=\"none\" stroke=\"#4BE0C3\" stroke-width=\"1.5\"/>\n </g>\n <g class=\"wave d5\"><rect class=\"cell\" x=\"172.5\" y=\"281.2\" width=\"142.5\" height=\"43.8\" rx=\"4\" fill=\"#4BE0C3\" opacity=\"0.56\"/></g>\n <g class=\"wave d6\"><rect class=\"cell\" x=\"325\" y=\"281.2\" width=\"142.5\" height=\"43.8\" rx=\"4\" fill=\"#4BE0C3\" opacity=\"0.36\"/></g>\n <g class=\"wave d7\"><rect class=\"cell\" x=\"477.5\" y=\"281.2\" width=\"142.5\" height=\"43.8\" rx=\"4\" fill=\"#4BE0C3\" opacity=\"0.2\"/></g>\n\n <!-- row 6 (weakest row overall) -->\n <g class=\"wave d5\"><rect class=\"cell\" x=\"20\" y=\"336\" width=\"142.5\" height=\"43.8\" rx=\"4\" fill=\"#4BE0C3\" opacity=\"0.36\"/></g>\n <g class=\"wave d6\"><rect class=\"cell\" x=\"172.5\" y=\"336\" width=\"142.5\" height=\"43.8\" rx=\"4\" fill=\"#4BE0C3\" opacity=\"0.2\"/></g>\n <g class=\"wave d7\"><rect class=\"cell\" x=\"325\" y=\"336\" width=\"142.5\" height=\"43.8\" rx=\"4\" fill=\"#4BE0C3\" opacity=\"0.08\"/></g>\n <g class=\"wave d8\"><rect class=\"cell\" x=\"477.5\" y=\"336\" width=\"142.5\" height=\"43.8\" rx=\"4\" fill=\"#4BE0C3\" opacity=\"0.08\"/></g>\n</svg>\n";
</script>
<div style="--lk-accent: #4BE0C3; --lk-bg: #0A0F14;">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 640 400" role="img" aria-label="Heatmap grid graphic — decorative" class="lk-block" data-lk="panel-topic-heatmap" data-lk-contract="1">
<title>Heatmap grid graphic</title>
<desc>Decorative heatmap grid graphic. Illustrative shape only; any implied data is fictional.</desc>
<style>
/* lk-contract v1 — synced from blocks/_contract/header.css */
[data-lk="panel-topic-heatmap"] {
--_accent: var(--lk-accent, #4BE0C3);
--_bg: var(--lk-bg, #0A0F14);
--_radius: var(--lk-radius, 12px);
--_i: oklch(from var(--_bg) clamp(0.14, (0.68 - l) * 999, 0.93) min(c, 0.03) h);
--_i2: color-mix(in oklab, var(--_i) 62%, transparent);
--_i3: color-mix(in oklab, var(--_i) 42%, transparent);
--_hair: color-mix(in oklab, var(--_i) 8%, transparent);
--_g: var(--lk-grid, color-mix(in oklab, var(--_i) 9%, transparent));
--_surf: color-mix(in oklab, var(--_accent) 3%, var(--_bg));
--_soft: color-mix(in oklab, var(--_accent) 24%, transparent);
--_faint: color-mix(in oklab, var(--_accent) 12%, transparent);
--_glow: color-mix(in oklab, var(--_accent) 55%, var(--_bg));
color: var(--_accent);
font-family: var(--lk-font, 'Inter','Neue Haas Grotesk','Helvetica Neue',Arial,sans-serif);
}
/* base ink: text flips with the bg via --_i; dim/semantic classes override (see CONVENTIONS.md) */
[data-lk="panel-topic-heatmap"] text,
[data-lk="panel-topic-heatmap"] tspan { fill: var(--_i); }
/* Layer 3: block-specific — every selector MUST start with [data-lk="panel-topic-heatmap"] */
[data-lk="panel-topic-heatmap"] .card { fill: var(--_surf); stroke: var(--_hair); rx: var(--_radius); }
[data-lk="panel-topic-heatmap"] .grid { fill: none; stroke: var(--_g); stroke-width: 1; }
[data-lk="panel-topic-heatmap"] .hair { stroke: var(--_hair); stroke-width: 1; }
[data-lk="panel-topic-heatmap"] .cell { fill: var(--_accent); rx: calc(var(--_radius) / 3); }
[data-lk="panel-topic-heatmap"] .hot { fill: none; stroke: var(--_accent); stroke-width: 1.5; rx: calc(var(--_radius) / 3); }
[data-lk="panel-topic-heatmap"] .empty { fill: none; stroke: var(--_i3); stroke-width: 1; stroke-dasharray: 3 2; rx: calc(var(--_radius) / 3); }
[data-lk="panel-topic-heatmap"] .ramp { fill: var(--_accent); rx: calc(var(--_radius) / 6); }
/* Hover motion (opt-out): 2 stages. (1) every data cell (fill plus its hot-ring, kept
together) fades and scales in as a diagonal wave, staggered by row+col so it sweeps
top-left to bottom-right. (2) once the wave lands, the hot-ring cells pulse once,
then the dashed no-data cell fades in last. Off for reduced-motion visitors; set the
motion token to 0 to force off. */
[data-lk="panel-topic-heatmap"] .wave { transform-box: fill-box; transform-origin: center; }
[data-lk="panel-topic-heatmap"] .pulse { transform-box: fill-box; transform-origin: center; }
@media (prefers-reduced-motion: no-preference) {
[data-lk="panel-topic-heatmap"]:hover .wave { animation: lk-panel-topic-heatmap-wave calc(var(--lk-motion, 1) * .4s) cubic-bezier(.22,.61,.36,1) both; }
[data-lk="panel-topic-heatmap"]:hover .d1 { animation-delay: calc(var(--lk-motion, 1) * .03s); }
[data-lk="panel-topic-heatmap"]:hover .d2 { animation-delay: calc(var(--lk-motion, 1) * .06s); }
[data-lk="panel-topic-heatmap"]:hover .d3 { animation-delay: calc(var(--lk-motion, 1) * .09s); }
[data-lk="panel-topic-heatmap"]:hover .d4 { animation-delay: calc(var(--lk-motion, 1) * .12s); }
[data-lk="panel-topic-heatmap"]:hover .d5 { animation-delay: calc(var(--lk-motion, 1) * .15s); }
[data-lk="panel-topic-heatmap"]:hover .d6 { animation-delay: calc(var(--lk-motion, 1) * .18s); }
[data-lk="panel-topic-heatmap"]:hover .d7 { animation-delay: calc(var(--lk-motion, 1) * .21s); }
[data-lk="panel-topic-heatmap"]:hover .d8 { animation-delay: calc(var(--lk-motion, 1) * .24s); }
[data-lk="panel-topic-heatmap"]:hover .pulse { animation: lk-panel-topic-heatmap-pulse calc(var(--lk-motion, 1) * .35s) ease-out both; animation-delay: calc(var(--lk-motion, 1) * .64s); }
[data-lk="panel-topic-heatmap"]:hover .fade { animation: lk-panel-topic-heatmap-fade calc(var(--lk-motion, 1) * .35s) ease-out both; animation-delay: calc(var(--lk-motion, 1) * .95s); }
}
@keyframes lk-panel-topic-heatmap-wave { from { opacity: 0; transform: scale(.6); } to { opacity: 1; transform: scale(1); } }
@keyframes lk-panel-topic-heatmap-pulse { 0% { transform: scale(1); } 50% { transform: scale(1.3); } 100% { transform: scale(1); } }
@keyframes lk-panel-topic-heatmap-fade { from { opacity: 0; } to { opacity: 1; } }
</style>
<rect class="card" x=".5" y=".5" width="639" height="399" rx="12" fill="#0E141B" stroke="#1A2128"/>
<!-- réseau crosses: dead corners of the margin band, on the grid token (silenced when lk-grid is transparent) -->
<path class="grid" d="M27 25h6M30 22v6" fill="none" stroke="#1C262C" stroke-width="1"/>
<path class="grid" d="M607 391h6M610 388v6" fill="none" stroke="#1C262C" stroke-width="1"/>
<!-- legend ramp: 5-step opacity swatches, single accent hue, centered above the grid -->
<rect class="ramp" x="277" y="20" width="14" height="10" rx="2" fill="#4BE0C3" opacity="0.08"/>
<rect class="ramp" x="295" y="20" width="14" height="10" rx="2" fill="#4BE0C3" opacity="0.2"/>
<rect class="ramp" x="313" y="20" width="14" height="10" rx="2" fill="#4BE0C3" opacity="0.36"/>
<rect class="ramp" x="331" y="20" width="14" height="10" rx="2" fill="#4BE0C3" opacity="0.56"/>
<rect class="ramp" x="349" y="20" width="14" height="10" rx="2" fill="#4BE0C3" opacity="0.8"/>
<line class="hair" x1="20" y1="50" x2="620" y2="50" stroke="#1A2128" stroke-width="1"/>
<!-- 6x4 matrix: single-hue accent cells, opacity steps encode value; grid expanded edge to edge -->
<!-- row 1 -->
<g class="wave"><rect class="cell" x="20" y="62" width="142.5" height="43.8" rx="4" fill="#4BE0C3" opacity="0.56"/></g>
<g class="wave d1"><rect class="cell" x="172.5" y="62" width="142.5" height="43.8" rx="4" fill="#4BE0C3" opacity="0.56"/></g>
<g class="wave d2"><rect class="cell" x="325" y="62" width="142.5" height="43.8" rx="4" fill="#4BE0C3" opacity="0.2"/></g>
<g class="wave d3"><rect class="cell" x="477.5" y="62" width="142.5" height="43.8" rx="4" fill="#4BE0C3" opacity="0.08"/></g>
<!-- row 2 (hot cell in column 2) -->
<g class="wave d1"><rect class="cell" x="20" y="116.8" width="142.5" height="43.8" rx="4" fill="#4BE0C3" opacity="0.56"/></g>
<g class="wave d2">
<rect class="cell" x="172.5" y="116.8" width="142.5" height="43.8" rx="4" fill="#4BE0C3" opacity="0.8"/>
<rect class="hot pulse" x="172.5" y="116.8" width="142.5" height="43.8" rx="4" fill="none" stroke="#4BE0C3" stroke-width="1.5"/>
</g>
<g class="wave d3"><rect class="cell" x="325" y="116.8" width="142.5" height="43.8" rx="4" fill="#4BE0C3" opacity="0.36"/></g>
<g class="wave d4"><rect class="cell" x="477.5" y="116.8" width="142.5" height="43.8" rx="4" fill="#4BE0C3" opacity="0.2"/></g>
<!-- row 3 -->
<g class="wave d2"><rect class="cell" x="20" y="171.6" width="142.5" height="43.8" rx="4" fill="#4BE0C3" opacity="0.56"/></g>
<g class="wave d3"><rect class="cell" x="172.5" y="171.6" width="142.5" height="43.8" rx="4" fill="#4BE0C3" opacity="0.36"/></g>
<g class="wave d4"><rect class="cell" x="325" y="171.6" width="142.5" height="43.8" rx="4" fill="#4BE0C3" opacity="0.2"/></g>
<g class="wave d5"><rect class="cell" x="477.5" y="171.6" width="142.5" height="43.8" rx="4" fill="#4BE0C3" opacity="0.08"/></g>
<!-- row 4 (column 4 has no data — dashed empty cell) -->
<g class="wave d3"><rect class="cell" x="20" y="226.4" width="142.5" height="43.8" rx="4" fill="#4BE0C3" opacity="0.2"/></g>
<g class="wave d4"><rect class="cell" x="172.5" y="226.4" width="142.5" height="43.8" rx="4" fill="#4BE0C3" opacity="0.36"/></g>
<g class="wave d5"><rect class="cell" x="325" y="226.4" width="142.5" height="43.8" rx="4" fill="#4BE0C3" opacity="0.08"/></g>
<rect class="empty fade" x="477.5" y="226.4" width="142.5" height="43.8" rx="4" fill="none" stroke="#E6EDEE6B" stroke-width="1" stroke-dasharray="3 2"/>
<!-- row 5 (hottest row — column 1 carries the top hot-ring cell) -->
<g class="wave d4">
<rect class="cell" x="20" y="281.2" width="142.5" height="43.8" rx="4" fill="#4BE0C3" opacity="0.8"/>
<rect class="hot pulse" x="20" y="281.2" width="142.5" height="43.8" rx="4" fill="none" stroke="#4BE0C3" stroke-width="1.5"/>
</g>
<g class="wave d5"><rect class="cell" x="172.5" y="281.2" width="142.5" height="43.8" rx="4" fill="#4BE0C3" opacity="0.56"/></g>
<g class="wave d6"><rect class="cell" x="325" y="281.2" width="142.5" height="43.8" rx="4" fill="#4BE0C3" opacity="0.36"/></g>
<g class="wave d7"><rect class="cell" x="477.5" y="281.2" width="142.5" height="43.8" rx="4" fill="#4BE0C3" opacity="0.2"/></g>
<!-- row 6 (weakest row overall) -->
<g class="wave d5"><rect class="cell" x="20" y="336" width="142.5" height="43.8" rx="4" fill="#4BE0C3" opacity="0.36"/></g>
<g class="wave d6"><rect class="cell" x="172.5" y="336" width="142.5" height="43.8" rx="4" fill="#4BE0C3" opacity="0.2"/></g>
<g class="wave d7"><rect class="cell" x="325" y="336" width="142.5" height="43.8" rx="4" fill="#4BE0C3" opacity="0.08"/></g>
<g class="wave d8"><rect class="cell" x="477.5" y="336" width="142.5" height="43.8" rx="4" fill="#4BE0C3" opacity="0.08"/></g>
</svg>
</div>