/* map.css — the map overlay (map.js). Only .csm- selectors. Tokens come from app.css (--ink, --go …) with literal
   fallbacks so tools/map-lab.html works on its own; .csm-dark / .csm-light pin the palette to the map's own setting.
   The squares themselves are drawn on a canvas by map.js (solid = website health, CSMap.HEALTH; hollow = not checked;
   green ring = you looked, ink ring = on the sheet, blue / purple = Justin / Dennis); this file styles the DOM around
   them: the heat swath's canvas, the town labels, the selected ring, the effects, the keyboard stand-in — and the name
   tag, which lives on document.body (position:fixed) so it always sits above the floating cards. */
.csm-map{overflow:hidden;-webkit-tap-highlight-color:transparent}
.csm-map.csm-over-dot .maplibregl-canvas,.csm-map.csm-over-town .maplibregl-canvas{cursor:pointer}
.csm-layer{
  --csm-bg:var(--bg,#faf9f5); --csm-ink:var(--ink,#141413); --csm-ink-2:var(--ink-2,#4c4b45); --csm-ink-3:var(--ink-3,#6e6d66); --csm-ink-4:var(--ink-4,#a8a69d);
  --csm-line:var(--line,#14141338); --csm-line-soft:var(--line-soft,#1414131c); --csm-go:var(--go,#3f6b2a); --csm-clay:var(--accent,#c15f3c);
  --csm-blue:var(--syn-blue,#3065d7); --csm-purple:var(--syn-purple,#914dbe); --csm-land:#faf9f5;
  --csm-ease:var(--ease-out,cubic-bezier(.19,1,.22,1));
  --csm-mono:var(--mono,"Geist Mono",ui-monospace,"SF Mono",Menlo,monospace); --csm-sans:var(--sans,"Inter Tight","Helvetica Neue",-apple-system,system-ui,sans-serif);
  position:absolute;left:0;top:0;pointer-events:none;overflow:hidden;contain:layout style;
  font-family:var(--csm-sans);color:var(--csm-ink);-webkit-font-smoothing:antialiased;z-index:2
}
@media (prefers-color-scheme:dark){.csm-layer{
  --csm-bg:var(--bg,#141413); --csm-ink:var(--ink,#faf9f5); --csm-ink-2:var(--ink-2,#b0aea5); --csm-ink-3:var(--ink-3,#87867f); --csm-ink-4:var(--ink-4,#5e5d59);
  --csm-line:var(--line,#faf9f529); --csm-line-soft:var(--line-soft,#faf9f517); --csm-go:var(--go,#9ac29a); --csm-clay:var(--accent,#d97757);
  --csm-blue:var(--syn-blue,#82aaff); --csm-purple:var(--syn-purple,#c792ea); --csm-land:#141413
}}
.csm-layer.csm-light{
  --csm-bg:#faf9f5; --csm-ink:#141413; --csm-ink-2:#4c4b45; --csm-ink-3:#6e6d66; --csm-ink-4:#a8a69d; --csm-line:#14141338; --csm-line-soft:#1414131c;
  --csm-go:#3f6b2a; --csm-clay:#c15f3c; --csm-blue:#3065d7; --csm-purple:#914dbe; --csm-land:#faf9f5
}
.csm-layer.csm-dark{
  --csm-bg:#141413; --csm-ink:#faf9f5; --csm-ink-2:#b0aea5; --csm-ink-3:#87867f; --csm-ink-4:#5e5d59; --csm-line:#faf9f529; --csm-line-soft:#faf9f517;
  --csm-go:#9ac29a; --csm-clay:#d97757; --csm-blue:#82aaff; --csm-purple:#c792ea; --csm-land:#141413
}
.csm-heat,.csm-canvas,.csm-towns,.csm-fx{position:absolute;left:0;top:0;pointer-events:none}
/* the swath: --heat-o is set by map.js from the zoom (1 to z15, 0 at z16); while zooming it dims to .3 and is redrawn on settle */
.csm-heat{z-index:0;transform-origin:0 0;image-rendering:auto;will-change:transform,opacity;opacity:var(--heat-o,1);transition:opacity .35s ease}
.csm-heat.is-zoom{opacity:calc(var(--heat-o,1) * .3);transition:opacity .18s ease}
.csm-heat.is-empty,.csm-layer.no-heat .csm-heat{opacity:0}
.csm-heat.csm-in{animation:csm-heat-in 1.4s ease both .25s}
@keyframes csm-heat-in{from{opacity:0}to{opacity:var(--heat-o,1)}}
.csm-canvas{z-index:1}.csm-towns{z-index:2}.csm-fx{z-index:3}

/* ---------- the squares are drawn on the canvas (map.js); these are the DOM pieces around them ---------- */
/* selected: a static 1.5px ring in the square's own health colour, 2px outside its mat (the square itself tweens to 1.6×) */
.csm-selring{position:absolute;left:0;top:0;width:0;height:0;pointer-events:none;--s:20px;--c:var(--csm-ink)}
.csm-selring[hidden]{display:none}
.csm-selring::before{content:"";position:absolute;left:calc(var(--s) / -2);top:calc(var(--s) / -2);width:var(--s);height:var(--s);box-shadow:0 0 0 1.5px var(--c)}

/* ---------- the name tag: on document.body, fixed, over everything on Home; 12px mono pill, --lift-2 ----------
   line 1 the name · line 2 kind · town · line 3 the deciding fact in the health colour (+ the price in green, + who looked)
   .is-pick lists the two squares under a finger, each row a button that opens that one */
.csm-tag{
  --tag-bg:var(--bg,#faf9f5); --tag-ink:var(--ink,#141413); --tag-ink-3:var(--ink-3,#7b7a72); --tag-line:var(--line,#14141338); --tag-raised:var(--bg-raised,#f1efe8);
  --tag-shadow:inset 0 0 0 1px var(--tag-line);
  --tag-mono:var(--mono,"Geist Mono",ui-monospace,"SF Mono",Menlo,monospace); --tag-ease:var(--ease-out,cubic-bezier(.19,1,.22,1));
  position:fixed;left:0;top:0;z-index:80;pointer-events:none;width:max-content;max-width:min(272px,calc(100vw - 16px));display:flex;align-items:center;gap:10px;
  padding:6px 10px;border-radius:0;background:var(--tag-bg);color:var(--tag-ink);box-shadow:var(--tag-shadow);
  font:400 12px/1.35 var(--tag-mono);letter-spacing:0;translate:-50% -100%;transform-origin:50% 100%;-webkit-font-smoothing:antialiased
}
@media (prefers-color-scheme:dark){.csm-tag{--tag-bg:var(--bg,#141413);--tag-ink:var(--ink,#faf9f5);--tag-ink-3:var(--ink-3,#87867f);--tag-line:var(--line,#faf9f529);--tag-raised:var(--bg-raised,#1a1a18);
  --tag-shadow:inset 0 0 0 1px var(--tag-line)}}
.csm-tag.csm-light{--tag-bg:#faf9f5;--tag-ink:#141413;--tag-ink-3:#7b7a72;--tag-line:#1414131c;--tag-raised:#f1efe8;--tag-shadow:inset 0 0 0 1px #14141338}
.csm-tag.csm-dark{--tag-bg:#141413;--tag-ink:#faf9f5;--tag-ink-3:#87867f;--tag-line:#faf9f517;--tag-raised:#1a1a18;--tag-shadow:inset 0 0 0 1px #faf9f529}
.csm-tag[hidden]{display:none}
.csm-tag.is-below{translate:-50% 0;transform-origin:50% 0}
.csm-tag.is-in{animation:csm-tag-in .22s var(--tag-ease) both}
.csm-tag.is-out{animation:csm-tag-out .12s ease both}
@keyframes csm-tag-in{from{opacity:0;scale:.96}to{opacity:1;scale:1}}
@keyframes csm-tag-out{from{opacity:1;scale:1}to{opacity:0;scale:.96}}
.csm-tag-pic{flex:none;width:28px;height:28px;border-radius:0;overflow:hidden;background:var(--tag-raised)}
.csm-tag-pic img{display:block;width:100%;height:100%;object-fit:cover}
.csm-tag-t{display:flex;flex-direction:column;gap:1px;min-width:0}
.csm-tag-t>b{font-weight:500;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;max-width:224px}
.csm-tag-s{color:var(--tag-ink-3);white-space:nowrap;overflow:hidden;text-overflow:ellipsis;max-width:224px}
.csm-tag-f{display:block;font-style:normal;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;max-width:224px}
.csm-tag-f u{text-decoration:none}
.csm-tag-f .csm-tag-\${color:var(--go,#3f6b2a)}
.csm-tag.csm-dark .csm-tag-f .csm-tag-\${color:#9ac29a}
.csm-tag.csm-light .csm-tag-f .csm-tag-\${color:#3f6b2a}
.csm-tag.is-pick{pointer-events:auto;padding:8px 8px 8px 12px;border-radius:0;translate:-50% calc(-100% - 8px)}
.csm-tag.is-pick.is-below{translate:-50% 8px}
.csm-tag.is-pick>.csm-tag-t>b{color:var(--tag-ink-3);font-weight:400;padding:0 4px 4px}
.csm-tag-row{display:flex;align-items:center;gap:8px;width:100%;min-height:36px;margin:0;padding:6px 6px 6px 8px;border:0;border-radius:0;background:none;color:var(--tag-ink);
  font:inherit;text-align:left;cursor:pointer;-webkit-appearance:none;appearance:none}
.csm-tag-row:hover,.csm-tag-row:focus-visible{background:var(--tag-raised);outline:none}
.csm-tag-row i{flex:none;width:8px;height:8px}
.csm-tag-row i.o{background:none!important;box-shadow:inset 0 0 0 1px var(--tag-ink-3)}
.csm-tag-row span{flex:1;min-width:0;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;max-width:200px}
.csm-tag-row u{text-decoration:none;color:var(--tag-ink-3)}

/* keyboard: one stand-in sits over the focused square (arrow keys rove, Enter opens) */
.csm-focus{position:absolute;left:0;top:0;width:1px;height:1px;z-index:5;padding:0;margin:0;border:0;border-radius:4px;background:transparent;opacity:1;
  pointer-events:none;-webkit-appearance:none;appearance:none;outline:none;color:transparent}
.csm-focus:focus-visible{box-shadow:0 0 0 2px var(--csm-ink),0 0 0 4px var(--csm-bg)}
.csm-sr{position:absolute;width:1px;height:1px;overflow:hidden;clip:rect(0 0 0 0);clip-path:inset(50%);white-space:nowrap}

/* ---------- town labels: Geist Mono caps on a square knockout of the page (Oct 8 plan §5) ---------- */
.csm-town{position:absolute;left:0;top:0;white-space:nowrap;font:400 .6875rem/1.4 var(--csm-mono);color:var(--csm-ink-3);
  padding:0 4px;background:var(--csm-bg);opacity:0;transition:opacity .45s ease;will-change:transform,opacity;pointer-events:none}
.csm-town.r1{color:var(--csm-ink-2)}
.csm-town.r3{color:var(--csm-ink-3)}
.csm-town.is-on{opacity:1}

/* ---------- effects: the done ring, the "just checked" ping, me ---------- */
/* the Sweep's scanline: 1px of ink across the map on the band being read; it eases to the next band */
.csm-scanline{position:absolute;left:0;top:0;height:1px;background:var(--csm-ink);opacity:.7;pointer-events:none}
.csm-scanline.ease{transition:transform .4s cubic-bezier(.19,1,.22,1)}
.csm-scanline[hidden]{display:none}
/* the scan's locate marks: four ink L-brackets close on the square; a dithered band steps down inside them only while
   the request is out */
.csm-scan{position:absolute;left:0;top:0;width:0;height:0;pointer-events:none;--b:48px;--k:9px}
.csm-scan[hidden]{display:none}
.csm-scan b{position:absolute;width:var(--k);height:var(--k);border:0 solid var(--csm-ink)}
.csm-scan .tl{left:calc(var(--b) / -2);top:calc(var(--b) / -2);border-width:2px 0 0 2px;--x:-1;--y:-1}
.csm-scan .tr{left:calc(var(--b) / 2 - var(--k));top:calc(var(--b) / -2);border-width:2px 2px 0 0;--x:1;--y:-1}
.csm-scan .bl{left:calc(var(--b) / -2);top:calc(var(--b) / 2 - var(--k));border-width:0 0 2px 2px;--x:-1;--y:1}
.csm-scan .br{left:calc(var(--b) / 2 - var(--k));top:calc(var(--b) / 2 - var(--k));border-width:0 2px 2px 0;--x:1;--y:1}
.csm-scan.on b{animation:csm-brk .2s steps(4) both}
.csm-scan.out b{animation:csm-brk-out .2s steps(4) both}
@keyframes csm-brk{from{transform:translate(calc(var(--x) * 14px),calc(var(--y) * 14px));opacity:0}}
@keyframes csm-brk-out{to{transform:translate(calc(var(--x) * 14px),calc(var(--y) * 14px));opacity:0}}
.csm-scan s{position:absolute;left:calc(var(--b) / -2 + 5px);top:calc(var(--b) / -2 + 4px);width:calc(var(--b) - 10px);height:6px;background:repeating-linear-gradient(90deg,var(--csm-ink) 0 1px,transparent 1px 3px);opacity:0;transition:opacity .2s}
.csm-scan.busy s{opacity:.55;animation:csm-band 1.2s steps(6) infinite}
@keyframes csm-band{to{transform:translateY(calc(var(--b) - 14px))}}
.csm-ring{position:absolute;left:0;top:0;width:0;height:0;pointer-events:none;--s:12px;--c:var(--csm-go)}
.csm-ring::before{content:"";position:absolute;left:calc(var(--s) / -2);top:calc(var(--s) / -2);width:var(--s);height:var(--s)}
.csm-ring.csm-pulse::before{box-shadow:0 0 0 2px var(--csm-go);animation:csm-ring 1.2s var(--csm-ease) both}
.csm-ring.csm-ping::before{box-shadow:0 0 0 2px var(--c);animation:csm-ping 1s cubic-bezier(.2,.7,.3,1) both}
@keyframes csm-ring{from{opacity:1;transform:scale(1)}to{opacity:0;transform:scale(3)}}
@keyframes csm-ping{from{opacity:.95;transform:scale(1)}to{opacity:0;transform:scale(4.2)}}
.csm-me{position:absolute;left:0;top:0;width:0;height:0;pointer-events:none;--r:24px}
.csm-me b{position:absolute;left:-4px;top:-4px;width:8px;height:8px;background:var(--me-c,var(--csm-blue));box-shadow:0 0 0 1px var(--csm-bg)}
.csm-me::before{content:"";position:absolute;left:calc(var(--r) / -2);top:calc(var(--r) / -2);width:var(--r);height:var(--r);border:1px solid color-mix(in srgb,var(--me-c,var(--csm-blue)) 40%,transparent)}

.csm-attr{position:absolute;left:72px;bottom:4px;z-index:6;pointer-events:auto;padding:1px 5px;font:400 .6875rem/1.4 var(--csm-mono);letter-spacing:0;
  color:var(--csm-ink-3);background:var(--csm-bg);box-shadow:inset 1px 1px 0 var(--csm-line-soft);text-decoration:none}
.csm-attr[hidden]{display:none}
/* ---------- MapLibre's attribution: kept, small, quiet ---------- */
.csm-map .maplibregl-ctrl-attrib{font:400 .6875rem/1.4 var(--mono,"Geist Mono",ui-monospace,Menlo,monospace);background:var(--bg,#faf9f5)!important;color:var(--ink-3,#6e6d66);border-radius:0!important;box-shadow:inset 1px 1px 0 var(--line-soft,#1414131c)}
.csm-map .maplibregl-ctrl-attrib-button{border-radius:0!important}
.csm-map .maplibregl-ctrl-attrib a{color:inherit}
.csm-map .maplibregl-ctrl-attrib.maplibregl-compact{min-height:20px;border-radius:0}
.csm-map .maplibregl-ctrl-attrib-button{transform:scale(.8)}

@media (prefers-reduced-motion:reduce){
  .csm-layer *,.csm-layer *::before,.csm-layer *::after,.csm-tag,.csm-tag *{animation:none!important;transition:none!important}
}
@media (prefers-reduced-motion:reduce){.csm-scan b,.csm-scan s,.csm-scanline{animation:none!important;transition:none!important}}

/* the edge marker: a row pointed at in the column whose square is off screen */
.csm-edge{position:absolute;left:0;top:0;z-index:6;pointer-events:none;padding:6px 8px;font:500 .6875rem/1 var(--mono,ui-monospace,monospace);white-space:nowrap;color:var(--ink,#141413);background:var(--bg,#faf9f5);box-shadow:0 0 0 1px var(--line,rgba(20,20,19,.2))}
.csm-edge[hidden]{display:none}
.csm-edge.is-in{animation:csmEdgeIn .2s cubic-bezier(.2,0,0,1) both}
@keyframes csmEdgeIn{from{opacity:0}}
@media (prefers-reduced-motion:reduce){.csm-edge.is-in{animation:none}}

/* a town's tally in SAVED from z12 out: how far through its leads you are */
.csm-tly{margin-left:6px;letter-spacing:0;color:var(--ink-3,#87867f)}
.csm-tly b{font-weight:400;color:var(--ink,#141413)}
.csm-tly i{font-style:normal;color:var(--stop-text,#c2382e)}
.csm-tly.done{color:var(--ink,#141413)}
