/* =========================================================================
   mapvitals.css — THE VITALS HONEYCOMB, floated over the live map.

   WHAT THIS IS
     The owner asked for the game's own HUD cluster on the website's live map
     (2026-08-10, with a screenshot of the in-game hexes beside the in-game
     minimap). This sheet dresses that cluster: a honeycomb of pointy-top
     hexagons that FILL FROM THE BOTTOM by percentage, exactly as the game
     draws them, plus the three nutrient meters underneath.

   NOT ONE COLOUR LIVES HERE. theme.css is the only sheet in this core allowed
   to decide a colour and the assembled-sheet gate enforces it, so every hue
   below is a `--mv-*` token emitted by the server's theme layer. The reasoning for
   why those particular hues are FIXED rather than themed — a player reads
   "blue is water, magenta is blood" from muscle memory built in the game
   itself — lives with the tokens, next to the same argument for the live
   card's own meaning colours.

   THE PENDING RULE, INHERITED FROM livecard.css
     A vital whose max the mod does not publish is UNKNOWN, not zero. Unknown
     draws no fill, no glow and a dash — a 0% hex reads as "you are dying",
     which would be a lie. `[data-known="false"]` is that state and it is
     deliberately dull.

   POSITIONING
     The cluster is absolutely positioned inside `.map-shell`, which is the
     map page's own positioned viewport. It sits bottom-left, clear of
     Leaflet's zoom control (bottom-right on this page) and above the credit
     line. On a phone it shrinks and keeps the same layout rather than
     re-flowing into a list: the honeycomb IS the thing he asked for.
   ========================================================================= */

/* -------------------------------------------------------------------------
   ISLA NOCTURA'S COPY. The canonical shared sheet takes every
   colour from `--mv-*` tokens emitted by the server's theme layer. This site is
   hand-built and has no such emitter, so the tokens are declared HERE, once,
   exactly as css/livecard.css declares its own `--lvc-*` set. Keep the two
   files' hues in step: the same animal must not read two colours on two pages.
   ------------------------------------------------------------------------- */
.map-vitals {
  --mv-health:  #FF4D6D;
  --mv-stamina: #2BD9C8;
  --mv-hunger:  #7ED957;
  --mv-thirst:  #4FC3F7;
  --mv-oxygen:  #8AB4FF;
  --mv-blood:   #FF5CD6;
  --mv-growth:  #F0B429;
  --mv-diet-a:  #F5C542;
  --mv-diet-b:  #FF8A7A;
  --mv-diet-c:  #9AD0FF;
  --mv-unknown: #6C7A8C;
  --mv-live:        #37D67A;
  --mv-live-halo:   rgba(55,214,122,.18);
  --mv-unknown-halo: rgba(108,122,140,.16);
  /* the island's own deep ground at glass alpha (site.css --ink #04070E) */
  --mv-plate:   rgba(4,7,14,.78);
  --mv-line:    rgba(255,255,255,.10);
  --mv-line-2:  rgba(255,255,255,.22);
  --mv-text:    #E9EDEF;          /* site.css --moon */
  --mv-dim:     rgba(233,237,239,.55);
  --mv-num-halo: rgba(0,0,0,.7);
}

.map-vitals {
  /* One number drives the whole honeycomb. Everything below is derived from
     it, so shrinking the cluster on a phone is a single custom-property
     change and never a second layout. */
  --mv-hex: 62px;

  /* BOTTOM CENTRE, and that is a MEASURED position, not a taste.
     The reference screenshot has the cluster on the left, and the left is
     exactly where this page cannot put it: `.map-panel` is 290 px wide,
     anchored top-left, and grows to the full height of the viewport, so a
     bottom-left cluster is buried under the legend and its toggle cannot even
     be clicked (found in a real browser at 1440x900, 1920x1080 and 1280x720 -
     the panel's box reached y=852 of an 838 px shell every time).
     Bottom centre is clear of the panel on the left and of the zoom control
     and credit line on the right at every width down to a phone, and it is
     where a game HUD sits anyway. */
  position: absolute;
  left: 50%;
  transform: translateX(-50%);
  bottom: 14px;
  /* This site's own map ladder (css/map.css): panel 800, bottom-right
     control 700. The cluster takes the map-overlay rung so the legend panel
     covers it when opened, which is the right way round. */
  z-index: 700;
  max-width: min(340px, calc(100vw - 28px));
  padding: 10px 12px 12px;
  border: 1px solid var(--mv-line);
  border-radius: 14px;
  background: var(--mv-plate);
  -webkit-backdrop-filter: blur(10px);
  backdrop-filter: blur(10px);
  box-shadow: 0 18px 44px -22px rgba(0,0,0,.9);
  color: var(--mv-text);
  font-family: var(--ui);
  /* Leaflet swallows drags and wheel events over its own container; this
     panel is a sibling overlay, so it must not become a dead zone that eats
     a pan the player meant for the map. Only the controls take pointers. */
  pointer-events: none;
}

.map-vitals[hidden] { display: none; }

.map-vitals > * { pointer-events: auto; }

/* ---------- head: title, freshness lamp, collapse ------------------------ */
.mv-head {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-bottom: 9px;
}

.mv-title {
  font: 600 11px/1 var(--ui);
  letter-spacing: .13em;
  text-transform: uppercase;
  color: var(--mv-dim);
  white-space: nowrap;
}

.mv-lamp {
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: var(--mv-unknown);
  box-shadow: 0 0 0 3px var(--mv-unknown-halo);
  flex: 0 0 auto;
}

.map-vitals[data-live="true"] .mv-lamp {
  background: var(--mv-live);
  box-shadow: 0 0 0 3px var(--mv-live-halo);
  animation: mv-pulse 2.6s ease-in-out infinite;
}

@keyframes mv-pulse {
  0%, 100% { opacity: 1; }
  50%      { opacity: .45; }
}

@media (prefers-reduced-motion: reduce) {
  .map-vitals[data-live="true"] .mv-lamp { animation: none; }
}

.mv-toggle {
  margin-left: auto;
  width: 24px;
  height: 24px;
  display: grid;
  place-items: center;
  border: 1px solid var(--mv-line);
  border-radius: 7px;
  background: transparent;
  color: var(--mv-dim);
  cursor: pointer;
  padding: 0;
  line-height: 0;
  transition: color .15s, border-color .15s, background .15s;
}

.mv-toggle:hover  { color: var(--mv-text); border-color: var(--mv-line-2); }
.mv-toggle:focus-visible { outline: 2px solid var(--mv-thirst); outline-offset: 2px; }
.mv-toggle svg { width: 13px; height: 13px; transition: transform .18s ease; }

.map-vitals[data-open="false"] .mv-body { display: none; }
.map-vitals[data-open="false"] .mv-toggle svg { transform: rotate(180deg); }

/* ---------- the honeycomb ----------------------------------------------- */
/* Rows overlap vertically by about a fifth of a hex, which is what makes a
   honeycomb a honeycomb rather than a grid of hexagons: the pointy top of a
   lower hex nests into the notch between two upper ones. */
.mv-comb {
  display: flex;
  flex-direction: column;
  align-items: center;
}

.mv-row {
  display: flex;
  gap: 5px;
}

.mv-row + .mv-row {
  margin-top: calc(var(--mv-hex) * -0.22);
}

.mv-cell {
  position: relative;
  width: var(--mv-hex);
  height: calc(var(--mv-hex) * 1.1);
  flex: 0 0 auto;
}

.mv-cell svg { position: absolute; inset: 0; width: 100%; height: 100%; display: block; }

/* The readout sits above the SVG. `pointer-events:none` so the title tooltip
   belongs to the cell as a whole and a hover never flickers between the
   number and the plate behind it. */
.mv-face {
  position: absolute;
  inset: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 1px;
  pointer-events: none;
}

.mv-ico { width: 40%; height: auto; opacity: .92; }
.mv-ico svg { position: static; width: 100%; height: auto; }

.mv-num {
  font: 700 12px/1 var(--ui);
  letter-spacing: .01em;
  text-shadow: 0 1px 3px var(--mv-num-halo);
}

.mv-cell[data-known="false"] .mv-num { color: var(--mv-unknown); font-weight: 600; }
.mv-cell[data-known="false"] .mv-ico { opacity: .38; }

/* A genuinely low reading earns a pulse. `data-low` is only ever set on a
   KNOWN vital, in the JS, for the same reason livecard.css refuses to warn on
   a pending bar. */
.mv-cell[data-low="true"] .mv-num { animation: mv-low 1.5s ease-in-out infinite; }

@keyframes mv-low {
  0%, 100% { opacity: 1; }
  50%      { opacity: .42; }
}

@media (prefers-reduced-motion: reduce) {
  .mv-cell[data-low="true"] .mv-num { animation: none; }
}


/* THE NEON EDGE. The reference is a game HUD drawn over terrain, and what
   makes those hexes read at a glance is that the outline GLOWS - the stroke
   alone disappears against a bright coastline. `currentColor` means each hex
   glows its own hue with no second colour declared anywhere.
   Only a KNOWN vital glows: a pending hex that glowed would be shouting an
   answer it does not have. */
.mv-cell[data-known="true"] .mv-edge {
  filter: drop-shadow(0 0 3px currentColor);
}

/* ---------- the nutrient strip ------------------------------------------ */
.mv-diet {
  display: flex;
  gap: 5px;
  justify-content: center;
  margin-top: 8px;
}

.mv-diet .mv-cell {
  width: calc(var(--mv-hex) * 0.72);
  height: calc(var(--mv-hex) * 0.79);
}

.mv-diet .mv-num { font-size: 10.5px; }
.mv-diet .mv-ico { width: 34%; }

/* ---------- the footer line --------------------------------------------- */
.mv-note {
  margin: 8px 0 0;
  font: 500 11.5px/1.45 var(--ui);
  color: var(--mv-dim);
  text-align: center;
}

.mv-note:empty { display: none; }

.mv-stage {
  display: inline-block;
  margin-left: 6px;
  padding: 1px 6px;
  border: 1px solid var(--mv-line);
  border-radius: 999px;
  font-size: 10.5px;
  color: var(--mv-text);
}

/* ---------- small screens ------------------------------------------------ */
/* The honeycomb keeps its shape and simply gets smaller. A phone that turned
   this into a stacked list would be showing something other than what the
   owner asked for. */
@media (max-width: 720px) {
  .map-vitals { --mv-hex: 48px; bottom: 10px; padding: 8px 9px 10px; }
  .mv-num { font-size: 10.5px; }
  .mv-title { font-size: 10px; }
}

@media (max-width: 400px) {
  .map-vitals { --mv-hex: 42px; }
}
