/* chart motion (charts lane). Entrance runs once per chart: html.motion .chart.in:not(.settled).
   Without html.motion (no JS) none of this applies and charts look static.
   Hooks added by the chart code: gx gy gn gc pop dr fd, plus --i (index) or --dl (ms delay). */

/* hover: the hovered mark brightens, its siblings dim */
.chart .hl { transition: opacity .2s cubic-bezier(.2, .8, .2, 1), filter .2s cubic-bezier(.2, .8, .2, 1); }
.chart svg:has(.hl:hover) .hl:not(:hover) { opacity: .45; }
.chart .hl:hover, .chart .hl.on { opacity: 1; filter: brightness(1.08); }

/* shared pieces */
html.motion .chart :is(.gx, .gy, .gn, .gc, .pop, .dr, .fd, .val, .inval, .indark) { transform-box: fill-box; }
html.motion .chart :is(.gx, .gy, .gn, .gc, .pop, .dr, .fd, .val, .inval, .indark) { --dly: var(--dl, min(calc(var(--i, 0) * 40ms), 160ms)); }
html.motion .chart .gx { transform-origin: 0 50%; }
html.motion .chart .gy { transform-origin: 50% 100%; }
html.motion .chart .gn { transform-origin: 50% 0; }
html.motion .chart .gc { transform-origin: 50% 50%; }
html.motion .chart .pop { transform-origin: 50% 50%; }

/* hidden until the chart scrolls into view */
html.motion .chart:not(.in) :is(.gx, .gy, .gn, .gc, .pop, .fd, .val, .inval, .indark) { opacity: 0; }
html.motion .chart:not(.in) .dr { stroke-dasharray: 1; stroke-dashoffset: 1; }

/* entrance */
html.motion .chart.in:not(.settled) :is(.gx, .gy, .gn) { animation: cm-grow-x .45s cubic-bezier(.2, .8, .2, 1) var(--dly) backwards; }
html.motion .chart.in:not(.settled) .gy, html.motion .chart.in:not(.settled) .gn { animation-name: cm-grow-y; }
html.motion .chart.in:not(.settled) .gc { animation: cm-grow-x .45s cubic-bezier(.2, .8, .2, 1) calc(var(--dly) + 60ms) backwards; }
html.motion .chart.in:not(.settled) .pop { animation: cm-pop .3s cubic-bezier(.2, .8, .2, 1) calc(var(--dly) + 120ms) backwards; }
html.motion .chart.in:not(.settled) :is(.fd, .val, .inval, .indark) { animation: cm-fade .3s cubic-bezier(.2, .8, .2, 1) calc(var(--dly) + 180ms) backwards; }
html.motion .chart.in:not(.settled) .dr { stroke-dasharray: 1; animation: cm-draw .6s cubic-bezier(.2, .8, .2, 1) backwards; }

@keyframes cm-grow-x { from { transform: scaleX(0); opacity: 0; } }
@keyframes cm-grow-y { from { transform: scaleY(0); opacity: 0; } }
@keyframes cm-pop { from { transform: scale(0); opacity: 0; } }
@keyframes cm-fade { from { opacity: 0; } }
@keyframes cm-draw { from { stroke-dashoffset: 1; } to { stroke-dashoffset: 0; } }

/* home map (#map is not a .chart). Dots sweep in left to right, then the grid and names fade in */
html.motion #map :is(.mp, .mf, .mt) { transform-box: fill-box; transform-origin: 50% 50%; }
html.motion #map:not(.in) :is(.mp, .mf, .mt) { opacity: 0; }
html.motion #map.in:not(.settled) .mf { animation: cm-fade .5s cubic-bezier(.2, .8, .2, 1) backwards; }
html.motion #map.in:not(.settled) .mp { animation: cm-pop .4s cubic-bezier(.34, 1.4, .64, 1) var(--dl, 0ms) backwards; }
html.motion #map.in:not(.settled) .mt { animation: cm-fade .3s cubic-bezier(.2, .8, .2, 1) 800ms backwards; }

/* map hover: the dot under the pointer goes solid with a dark ring, the rest step back */
#map circle[data-slug] { transition: opacity .2s cubic-bezier(.2, .8, .2, 1), fill-opacity .2s, stroke .2s, stroke-width .2s, transform .25s cubic-bezier(.34, 1.4, .64, 1); }
#map circle[data-slug]:hover { fill-opacity: 1; stroke: var(--ink); stroke-width: 1.5px; vector-effect: non-scaling-stroke; }
#map:not(.dim) svg:has(circle[data-slug]:hover) circle[data-slug]:not(:hover) { opacity: .35; }
html.motion #map.settled circle[data-slug]:hover { transform: scale(var(--hs, 1.2)); }
