/* css/coverage.css — P4-01. Fog-of-war coverage layer.
   Owned by P4-01. Ported from Adventure-Exploration-Map-v1.html.

   TWO RULES THIS FILE KEEPS.

   1. EVERY VISUAL VALUE IS A CUSTOM PROPERTY. The coverage layer paints onto a
      <canvas>, so a stylesheet cannot style it directly. js/coverage.js reads
      these properties ONCE at init (and again on refreshCoverageTheme()) with
      getComputedStyle and caches the parsed values, because calling
      getComputedStyle inside the per-tile paint loop would thrash layout on
      every pan. Change a colour here, not in the JS.

   2. NOTHING GLOBAL. No element selectors, no bare class names that another
      module might also use. Everything is either a --cov-* custom property on
      :root (the only place custom properties can live) or a class under the
      .atlas-cov- prefix. styles.css already defines a global `.panel` for the
      side sheet, which is exactly the collision this prefix avoids.

   LOADING: nothing links this file. index.html is owned by P1-01 and P1-12
   runs the integration pass, so js/coverage.js injects a <link> at module load
   (guarded by element id), the same pattern chrome.js, basemaps.js and
   elevation.js already use. INTEGRATION-NOTES.md carries the P1-12 request to
   replace that injection with a static <link>. P1-11: this file is fetched at
   runtime, so it must be in the service-worker precache list either way. */

:root {
  /* ---- fog --------------------------------------------------------------
     The unexplored wash. Alpha is the whole design: too opaque and the
     basemap stops being a map, too sheer and "unexplored" stops reading.
     0.86 is v1's value, verified against USGS Topo underneath.
     --cov-fog-low applies at zoom <= --cov-low-zoom-max, where one z14 cell is
     a few pixels and a heavy wash flattens the island into a black blob. */
  --cov-fog:            rgba(9, 13, 16, 0.86);
  --cov-fog-low:        rgba(9, 13, 16, 0.74);
  --cov-low-zoom-max:   11;

  /* ---- visited cells ----------------------------------------------------
     Fog mode clears the cell, then lays this tint back over it so a conquered
     tile reads as claimed rather than merely as a hole. Coverage mode fills
     with the same tint over an unfogged basemap. --accent is the hike accent
     from styles.css (#2ec4b6) expressed as rgba so canvas can use it. */
  --cov-visited-fill:   rgba(46, 196, 182, 0.20);
  --cov-visited-stroke: rgba(46, 196, 182, 0.85);
  --cov-visited-stroke-width: 1;

  /* Cell edge in CSS px below which the outline is skipped: at z10 a z14 cell
     is 16px and the grid reads; at z8 it is 4px and the outline is all you
     see. Skipping it is the low-zoom degradation, not a bug. */
  --cov-stroke-min-px:  10;
  /* Below this the tint is skipped too and the cell is only cleared. */
  --cov-tint-min-px:    2.5;
  /* Sub-pixel cells still get this much width so a lone tile never vanishes. */
  --cov-min-cell-px:    0.6;

  /* ---- heatmap ramp (mode 'heatmap') ------------------------------------
     Space-separated "r g b" triples, comma separated, cold to hot. Parsed
     once at init. Count is free; two or more stops. */
  --cov-heat-stops:     43 108 255, 46 196 182, 255 183 3, 230 57 70;
  --cov-heat-alpha:     0.72;

  /* ---- layer ------------------------------------------------------------ */
  --cov-layer-opacity:  1;

  /* ---- drop target + toast ---------------------------------------------- */
  --cov-drop-bg:        rgba(15, 20, 23, 0.82);
  --cov-drop-border:    2px dashed var(--accent, #2ec4b6);
  --cov-drop-radius:    1rem;
  --cov-drop-pad:       1.75rem 2.25rem;
  --cov-toast-bottom:   1.25rem;
  --cov-toast-pad:      0.5rem 0.875rem;
  --cov-toast-fade:     0.2s;
  --cov-toast-hold:     2600ms;   /* read by JS, not by CSS */
  /* Leaflet controls top out at 800 and styles.css puts chrome at 1000. The
     drop overlay covers the map only, so it sits above Leaflet and below the
     chrome. */
  --cov-z-drop:         850;
  --cov-z-toast:        860;
}

/* The overlay is appended to the map container (position: relative, courtesy
   of Leaflet) and is display:none until a drag enters the window. It must not
   eat pointer events when hidden, and it must eat them when shown so the drop
   lands on it rather than on a Leaflet pane. */
.atlas-cov-drop {
  position: absolute;
  inset: 0;
  z-index: var(--cov-z-drop);
  display: none;
  align-items: center;
  justify-content: center;
  background: var(--cov-drop-bg);
  color: var(--text, #e8eef1);
  font-family: var(--font, system-ui, sans-serif);
  text-align: center;
}

.atlas-cov-drop.atlas-cov-drop-on { display: flex; }

.atlas-cov-drop-box {
  border: var(--cov-drop-border);
  border-radius: var(--cov-drop-radius);
  padding: var(--cov-drop-pad);
  max-width: 82%;
  background: var(--bg-raised, #172026);
}

.atlas-cov-drop-title {
  margin: 0 0 0.375rem;
  font-size: 1.0625rem;
  font-weight: 700;
}

.atlas-cov-drop-hint {
  margin: 0;
  font-size: 0.8125rem;
  color: var(--text-dim, #9aabb5);
}

/* Import feedback. Bottom-centred over the map so it never covers the chrome
   or the panel, and above the safe-area inset on a phone. */
.atlas-cov-toast {
  position: absolute;
  left: 50%;
  bottom: calc(var(--cov-toast-bottom) + env(safe-area-inset-bottom, 0px));
  transform: translateX(-50%);
  z-index: var(--cov-z-toast);
  max-width: 88%;
  padding: var(--cov-toast-pad);
  border: 1px solid var(--line, #26333b);
  border-radius: var(--radius, 0.5rem);
  background: var(--bg-raised, #172026);
  color: var(--text, #e8eef1);
  font-family: var(--font, system-ui, sans-serif);
  font-size: 0.8125rem;
  line-height: 1.35;
  opacity: 0;
  pointer-events: none;
  transition: opacity var(--cov-toast-fade) ease;
}

.atlas-cov-toast.atlas-cov-toast-on { opacity: 1; }

@media (prefers-reduced-motion: reduce) {
  .atlas-cov-toast { transition: none; }
}
