/* ============================================================
   SANTA OLIVER — North Pole adventure map
   The map replaces the activity card grid. It always shows in
   full and scales to the screen, so nothing is ever parked off
   the side of a phone. The trade-off is that the name plaques
   baked into the artwork get small on a narrow screen, which is
   what the activity list underneath is for.
   ============================================================ */

/* The activity cards stay in the DOM because the fullscreen launcher moves
   those nodes into its window. Hiding the GRID (not the cards) keeps that
   working: once a card is moved out of this container it is no longer a
   descendant of a hidden element, so it shows normally in the window. */
.toy-grid.is-mapped { display: none; }

/* ---------------- vertical rhythm ----------------
   The old spacing was tuned for a heading, a subtitle and a grid of cards.
   With the map carrying its own banner and the heading now hidden, the same
   90px band above and below left it marooned: 236px between the countdown and
   the map, and 224px between the map and the note beneath it. These overrides
   live here, not in north-pole.css, because that file is shared with
   reindeer-hunt.html, which should keep its original spacing. */
.np-hero { padding-bottom: 48px; }
.np-section { padding: 46px 0 58px; }
.np-head { margin-bottom: 24px; }
.parent-note { margin-top: 30px; }

/* ---------------- compact hero on small screens ----------------
   On a phone the map is the point of this page, so the hero collapses to a
   title and a countdown strip rather than a full 60vh landing panel. The
   kicker and the lead paragraph are cut, the countdown boxes become small
   inline pills, and the decorative moon and sleigh go: at this height they
   would only appear as clipped fragments. */
@media (max-width: 899px) {
  .np-hero {
    min-height: 0;
    /* Clears the fixed nav, which is ~86px tall here because the logo's
       subtitle wraps. Measured, not guessed: at 76px the title collided. */
    padding: 98px 0 14px;
    display: block;
  }
  .np-hero .kicker,
  .np-hero p,
  .np-hero .moon-disc,
  .np-hero .flyer-mount { display: none; }
  .np-hero h1 {
    font-size: 24px;
    line-height: 1.14;
    margin: 0 0 9px;
    text-shadow: 0 2px 12px rgba(0, 0, 0, .45);
  }
  /* One line, not two. The markup is `Elf Training<br><em>Academy</em>`
     with no whitespace around the break, so hiding it alone renders
     "Elf TrainingAcademy" -- the space has to be put back explicitly. */
  .np-hero h1 br { display: none; }
  .np-hero h1 em { font-size: inherit; }
  .np-hero h1 em::before { content: "\00a0"; }

  .countdown { gap: 6px; margin: 0 0 5px; flex-wrap: nowrap; }
  .cd-unit {
    display: flex;
    align-items: baseline;
    justify-content: center;
    gap: 4px;
    width: auto;
    min-width: 0;
    flex: 0 1 auto;
    padding: 4px 9px;
    border-radius: 999px;
  }
  .cd-unit .n { font-size: 15px; }
  .cd-unit .l { font-size: 8px; letter-spacing: .1em; margin-top: 0; }
  .cd-foot { font-size: 9px; letter-spacing: .14em; }

  /* The decorative rule sat above a heading that is hidden anyway. */
  .np-head { display: none; }
}

@media (max-width: 620px) {
  .np-hero { padding: 94px 0 12px; }
  .np-section { padding: 22px 0 40px; }
  .parent-note { margin-top: 22px; }
}

.np-map {
  position: relative;
  margin: 0 auto;
  max-width: 1180px;
}

.np-map-scroll {
  overflow: hidden;
  border-radius: 18px;
  border: 1px solid rgba(255, 255, 255, 0.18);
  box-shadow: 0 16px 44px rgba(0, 0, 0, 0.38);
}

/* The whole map is always visible, at every width. It scales down rather than
   panning, so nothing is ever hidden off the side of a phone screen. */
.np-map-inner {
  position: relative;
  width: 100%;
  aspect-ratio: 1376 / 768;
}
.np-map-img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
  user-select: none;
  -webkit-user-drag: none;
}

/* ---------------- hotspots ---------------- */
.np-spot {
  position: absolute;
  padding: 0;
  border: 0;
  background: transparent;
  border-radius: 14px;
  cursor: pointer;
  /* Percentage boxes shrink with the map; on a small phone the smallest
     hotspot fell to 30x35. Children aim less precisely than adults, not more. */
  min-width: 44px;
  min-height: 44px;
  -webkit-tap-highlight-color: transparent;
  transition: background .16s ease, transform .16s ease;
}
@media (hover: hover) and (pointer: fine) {
  .np-spot:hover {
    background: rgba(255, 255, 255, 0.16);
    box-shadow: inset 0 0 0 2px rgba(255, 246, 214, 0.85), 0 6px 18px rgba(0, 0, 0, 0.3);
    outline: none;
  }
}
.np-spot:focus-visible {
  background: rgba(255, 255, 255, 0.16);
  box-shadow: inset 0 0 0 2px rgba(255, 246, 214, 0.85), 0 6px 18px rgba(0, 0, 0, 0.3);
  outline: none;
}
.np-spot:active { transform: scale(0.98); background: rgba(255, 255, 255, 0.16); }

/* Name repeated on hover/focus: the plaque is baked into the artwork and can
   be small once the map is scaled down. */
.np-spot-tip {
  position: absolute;
  left: 50%;
  bottom: -6px;
  transform: translate(-50%, 100%);
  padding: 5px 10px;
  border-radius: 8px;
  background: rgba(12, 24, 38, 0.94);
  color: #fff6de;
  font-family: var(--body, system-ui, sans-serif);
  font-size: 12.5px;
  font-weight: 700;
  white-space: nowrap;
  opacity: 0;
  pointer-events: none;
  transition: opacity .16s ease;
  z-index: 3;
}
@media (hover: hover) and (pointer: fine) {
  .np-spot:hover .np-spot-tip { opacity: 1; }
}
.np-spot:focus-visible .np-spot-tip { opacity: 1; }

/* Below this width the map has shrunk enough that a nowrap tooltip no longer
   fits inside it and gets clipped by the frame. Touch devices never hover, so
   nothing is lost; the labelled activity list is the path on small screens.
   Focused hotspots still announce themselves through their aria-label. */
@media (max-width: 899px) {
  .np-spot-tip { display: none; }
}

/* Outline every hotspot for tuning: append ?maphot=1 to the URL. */
.np-map--debug .np-spot { background: rgba(255, 90, 90, 0.28); box-shadow: inset 0 0 0 2px #ff4d4d; }
.np-map--debug .np-spot-tip { opacity: 1; }

/* ---------------- list fallback ---------------- */
.np-list { max-width: 1180px; margin: 12px auto 0; text-align: center; }
.np-list-toggle {
  padding: 12px 18px;
  min-height: 44px;
  font: inherit;
  font-size: 13.5px;
  font-weight: 600;
  color: var(--gold-200, #e3c878);
  background: rgba(255, 255, 255, 0.07);
  border: 1px solid rgba(255, 255, 255, 0.18);
  border-radius: 999px;
  cursor: pointer;
}
@media (hover: hover) and (pointer: fine) {
  .np-list-toggle:hover { background: rgba(255, 255, 255, 0.12); }
}
.np-list-toggle:active { background: rgba(255, 255, 255, 0.12); transform: scale(0.97); }
.np-list-toggle:focus-visible { outline: none; box-shadow: 0 0 0 3px rgba(200, 162, 74, .5); }

.np-list-panel {
  list-style: none;
  margin: 14px 0 0;
  padding: 0;
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(190px, 1fr));
  gap: 9px;
}
.np-list-panel[hidden] { display: none; }
.np-list-panel button {
  width: 100%;
  min-height: 48px;
  padding: 12px 14px;
  font: inherit;
  font-size: 14.5px;
  font-weight: 600;
  text-align: left;
  color: var(--snow, #fbfaf6);
  background: rgba(255, 255, 255, 0.08);
  border: 1px solid rgba(255, 255, 255, 0.16);
  border-radius: 12px;
  cursor: pointer;
}
@media (hover: hover) and (pointer: fine) {
  .np-list-panel button:hover { background: rgba(255, 255, 255, 0.14); }
}
.np-list-panel button:active { background: rgba(255, 255, 255, 0.14); }
.np-list-panel button:focus-visible { outline: none; box-shadow: 0 0 0 3px rgba(200, 162, 74, .5); }

@media (prefers-reduced-motion: reduce) {
  .np-spot, .np-spot-tip { transition: none; }
}

/* ---------------- short screens (landscape phones) ----------------
   Height, not width, is the scarce dimension here. A 16:9 map at full width
   is ~450px tall in a 390px-tall viewport, so it was pushed entirely below
   the fold. Size the map by height instead and trim the hero further.

   The orientation guard is load-bearing, not decoration. Keyed on height
   alone this fired in PORTRAIT too: a 320dp phone with browser chrome top and
   bottom leaves ~418px of viewport, well under 520. The map was then sized by
   height, its width resolved through the 1.79:1 image to ~390dp against ~290dp
   of room, and .np-map-scroll's overflow:hidden silently clipped the right
   third — "NORTH POLE ADVENTURE", "SANTA'S VILLAGE" and "WRITE A LETTER TO
   SANTA" all lost their ends, with no way to pan to them since np-map.js has
   no drag. That directly contradicted the promise eight rules above, that the
   whole map is visible at every width. */
@media (max-height: 520px) and (max-width: 899px) and (orientation: landscape) {
  .np-hero { padding: 90px 0 8px; }
  .np-hero h1 { font-size: 19px; margin-bottom: 6px; }
  .cd-unit { padding: 3px 7px; }
  .cd-unit .n { font-size: 13px; }
  .cd-unit .l { font-size: 7.5px; }
  .cd-foot { display: none; }
  .np-section { padding: 12px 0 24px; }
  .np-map-scroll { width: fit-content; max-width: 100%; margin-inline: auto; }
  .np-map-inner { width: auto; height: 52vh; }
}

/* ---------------- explore fullscreen ----------------
   Fitted to a phone the artwork renders its painted plaques ~3.5px tall, which
   is why the activity list starts open there. Legible text needs the map about
   three times the width of the screen, so exploring it means panning rather
   than fitting — and that needs more room than the page can spare. Fullscreen
   supplies the room and native overflow scrolling does the panning, so there
   is no drag code to maintain. */
.np-map-explore {
  position: absolute; right: 10px; bottom: 10px; z-index: 3;
  display: inline-flex; align-items: center; gap: 6px;
  min-height: 36px; padding: 7px 13px;
  border: 0; border-radius: 999px; cursor: pointer;
  font-family: var(--body); font-size: 13px; font-weight: 700;
  color: #10233a; background: rgba(255, 255, 255, 0.92);
  box-shadow: 0 6px 18px rgba(0, 0, 0, 0.35);
}
.np-map-explore:active { transform: scale(0.97); }
.np-map.is-fs .np-map-explore { display: none; }

body.np-map-fs { overflow: hidden; }

/* Below .np-win (z-index 100000) on purpose: a hotspot tapped in here opens
   its activity ON TOP, and closing that returns to the map still open. */
.np-map.is-fs {
  position: fixed; inset: 0; z-index: 120;
  margin: 0; max-width: none; background: #0b1626;
}
.np-map.is-fs .np-map-scroll {
  width: 100%; height: 100%;
  overflow: auto;
  -webkit-overflow-scrolling: touch;
  border: 0; border-radius: 0; box-shadow: none;
}
/* ~1000px puts the plaques near 12px, which is the entire point. Wider
   viewports just use their own width and need no panning at all. Both axes are
   set so this also overrides the landscape height-sizing rule above. */
.np-map.is-fs .np-map-inner { width: max(1000px, 100%); height: auto; }

.np-map-close {
  position: fixed; top: max(10px, env(safe-area-inset-top)); right: max(10px, env(safe-area-inset-right)); z-index: 4;
  min-width: 44px; min-height: 44px;
  display: none; align-items: center; justify-content: center;
  border: 0; border-radius: 999px; cursor: pointer;
  background: rgba(12, 27, 46, 0.86); color: #fff;
  box-shadow: 0 6px 18px rgba(0, 0, 0, 0.45);
}
.np-map.is-fs .np-map-close { display: inline-flex; }
