/*
 * List and map of the vacation pages (kinderjahre-app.de/urlaub/…).
 *
 * Loaded only by those pages (website/api/_lib/vacationPage.mjs), on top of
 * the directory shell's inline style: the cards themselves (.grid, .card,
 * .art, .body) are styled there, this file adds the two-column layout, the
 * postcode form, the map's look and the phone overlay. The behaviour is
 * /urlaub-karte.js; the markup both rely on is the DOM contract in
 * docs/superpowers/plans/2026-11-09-urlaub-seiten.md.
 *
 * Colours only from tokens.css. Where the map needs an opaque version of a
 * glass tone (a popup must not show the pins through), it is mixed from two
 * tokens below, never written as a value.
 *
 * States the script sets on <body>:
 *   .vac-on        the script runs and at least one destination has a pin
 *   .no-geo        no destination has a pin: no form, no map, no toggle
 *   .vac-map-open  the phone overlay is open
 * Without the script nothing here is interactive, so the form and the toggle
 * stay out of the way until .vac-on: a dead form would send the postcode to
 * the server as a query string, and the postcode never leaves the browser.
 */

.split,
.map-toggle,
.plz {
  /* --surface-card and --surface-raised laid over the ground, opaque. */
  --vac-solid-card: color-mix(in srgb, var(--text-primary) 15%, var(--ground));
  --vac-solid-raised: color-mix(in srgb, var(--text-primary) 25%, var(--ground));
  /* A shadow has to be darker than the ground it falls on. */
  --vac-shadow: color-mix(in srgb, var(--ground) 60%, transparent);
}

/* ── Postcode form ─────────────────────────────────────────────────────── */

.plz {
  display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-sm) var(--space-md);
  /* main spaces its children by --space-xxxl; the form belongs to the list. */
  margin-bottom: calc(-1 * var(--space-md));
  visibility: hidden;
}
body.vac-on .plz { visibility: visible; }
body.no-geo .plz { display: none; }
.plz label { font-weight: 700; }
.plz input {
  width: 8em; min-height: 44px; padding: 0 var(--space-lg);
  border-radius: var(--radius-full); border: 1px solid var(--border-default);
  background: var(--surface-inline); color: var(--text-primary);
  /* 16px: below it iOS zooms the page when the field takes focus. */
  font: inherit; font-size: var(--type-emphasis-size); font-variant-numeric: tabular-nums;
}
.plz input::placeholder { color: var(--text-secondary); opacity: 1; }
.plz input:focus-visible { outline: 2px solid var(--border-selected); outline-offset: 2px; }
.plz button[type="submit"],
.map-toggle,
.map-close,
.vac-pop-go {
  display: inline-flex; align-items: center; justify-content: center; gap: var(--space-sm);
  min-height: 44px; padding: 0 var(--space-xl); border: 0; border-radius: var(--radius-full);
  background: var(--border-selected); color: var(--text-on-accent);
  font: inherit; font-weight: 700; white-space: nowrap; text-decoration: none; cursor: pointer;
  transition: background var(--motion-fast);
}
.plz button[type="submit"]:hover,
.map-toggle:hover,
.map-close:hover,
.vac-pop-go:hover { background: var(--text-primary); }
#vac-plz-msg { flex: 0 0 100%; color: var(--text-secondary); }
#vac-plz-msg.is-error { color: var(--text-primary); font-weight: 700; }
.plz-reset {
  margin-left: var(--space-xs); padding: var(--space-sm) var(--space-xs); border: 0; background: none;
  color: var(--border-selected); font: inherit; font-weight: 700;
  text-decoration: underline; text-underline-offset: 3px; cursor: pointer;
}

/* The distance behind a card's place, written by the script. */
.dist { color: var(--text-primary); font-weight: 700; white-space: nowrap; }

/* ── List and map ──────────────────────────────────────────────────────── */

.split > :first-child { min-width: 0; }
.map-pane { display: none; }

.card.is-active,
a.card.is-active:hover {
  background: var(--surface-raised); border-color: var(--border-selected);
  box-shadow: 0 0 0 2px var(--border-selected), 0 8px 24px var(--shadow-glass);
}
li[data-id] { scroll-margin-block: var(--space-xxl); }

@media (min-width: 1024px) {
  /* List plus map needs the room: three cards beside the map on a wide
     screen instead of two. Band and footer follow, so the edges stay in line. */
  body:has(.map-pane):not(.no-geo) .wrap { max-width: 1360px; }

  .split {
    display: grid; grid-template-columns: minmax(0, 1fr) minmax(360px, 40%);
    gap: var(--space-xxl); align-items: start;
  }
  .map-pane {
    display: block; position: sticky; top: var(--space-lg);
    height: calc(100vh - 2 * var(--space-lg)); height: calc(100dvh - 2 * var(--space-lg));
    min-height: 320px; overflow: hidden; isolation: isolate;
    border: 1px solid var(--border-default); border-radius: var(--radius-xl);
    background: var(--surface-inline); box-shadow: 0 8px 24px var(--shadow-glass);
  }
  body.no-geo .split { display: block; }
  body.no-geo .map-pane { display: none; }
}

#vac-map { position: absolute; inset: 0; z-index: 0; }

/* "Karte wird geladen …" and the retry, centred over the empty pane. */
.vac-map-status {
  position: absolute; inset: 0; z-index: 1; display: flex; flex-direction: column;
  align-items: center; justify-content: center; gap: var(--space-md);
  padding: var(--space-xxl); text-align: center; color: var(--text-secondary);
}
.vac-map-status[hidden] { display: none; }
.vac-map-status button {
  min-height: 44px; padding: 0 var(--space-xl); border-radius: var(--radius-full);
  border: 1px solid var(--border-default); background: var(--surface-card); color: var(--text-primary);
  font: inherit; font-weight: 700; cursor: pointer;
}
.vac-map-status button:hover { background: var(--surface-raised); border-color: var(--border-selected); }

/* ── Phone: the toggle and the full-screen map ─────────────────────────── */

.map-toggle,
.map-close { display: none; }

@media (max-width: 1023.98px) {
  body.vac-on .map-toggle,
  body.vac-map-open .map-close {
    display: inline-flex; position: fixed; z-index: 900; left: 50%;
    bottom: calc(var(--space-xl) + env(safe-area-inset-bottom, 0px)); transform: translateX(-50%);
    min-height: 48px; padding: 0 var(--space-xxl);
    box-shadow: 0 8px 24px var(--vac-shadow);
  }
  body.vac-map-open .map-toggle { display: none; }
  .map-toggle::before,
  .map-close::before {
    content: ""; width: 18px; height: 18px; background: currentColor;
    -webkit-mask: var(--vac-icon) center / contain no-repeat; mask: var(--vac-icon) center / contain no-repeat;
  }
  /* Feather "map" and "list". A mask only uses the shape, the colour is the text's. */
  .map-toggle { --vac-icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2.4' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolygon points='1 6 1 22 8 18 16 22 23 18 23 2 16 6 8 2 1 6'/%3E%3Cline x1='8' y1='2' x2='8' y2='18'/%3E%3Cline x1='16' y1='6' x2='16' y2='22'/%3E%3C/svg%3E"); }
  .map-close { --vac-icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2.4' stroke-linecap='round' stroke-linejoin='round'%3E%3Cline x1='8' y1='6' x2='21' y2='6'/%3E%3Cline x1='8' y1='12' x2='21' y2='12'/%3E%3Cline x1='8' y1='18' x2='21' y2='18'/%3E%3Cline x1='3' y1='6' x2='3.01' y2='6'/%3E%3Cline x1='3' y1='12' x2='3.01' y2='12'/%3E%3Cline x1='3' y1='18' x2='3.01' y2='18'/%3E%3C/svg%3E"); }

  /* The pill floats over the page's last lines; give them room to scroll clear. */
  body.vac-on footer { padding-bottom: calc(2 * var(--space-xxl) + 72px); }

  body.vac-map-open { overflow: hidden; }
  body.vac-map-open .map-pane {
    display: block; position: fixed; inset: 0; z-index: 1000; isolation: isolate;
    background: var(--ground);
  }
  /* Keep Leaflet's corner controls clear of the notch and the home bar. */
  body.vac-map-open .leaflet-top { top: env(safe-area-inset-top, 0px); }
  body.vac-map-open .leaflet-bottom { bottom: env(safe-area-inset-bottom, 0px); }
}

/* ── The map's look: Leaflet's light defaults, taken to the dark page ──── */

.map-pane .leaflet-container {
  background: var(--ground); color: var(--text-primary);
  font-family: var(--font-family); font-size: var(--type-caption-size); line-height: var(--type-caption-line);
}
.map-pane .leaflet-container:focus-visible { outline: 2px solid var(--border-selected); outline-offset: -2px; }
.map-pane .leaflet-container a { color: inherit; }

/* Countries: a tone above the ground, the sea is the ground itself. Styled
   here and not through Leaflet's colour options, so the tokens stay the source. */
.vac-land { fill: var(--surface-inline); fill-opacity: 1; stroke: none; }
.vac-border { fill: none; stroke: var(--border-subtle); stroke-opacity: 1; stroke-width: 1; }

.vac-label { pointer-events: none; }
.vac-label[hidden] { display: none; }
.vac-label span {
  position: absolute; white-space: nowrap; color: var(--text-secondary);
  font-size: var(--type-micro-size); line-height: var(--type-micro-line); font-weight: 700;
  text-shadow: 0 0 3px var(--ground), 0 0 3px var(--ground);
}
.vac-label-country span { transform: translate(-50%, -50%); text-transform: uppercase; letter-spacing: 1px; }
.vac-label-city span { left: 7px; top: 0; transform: translateY(-50%); color: var(--text-primary); font-weight: 600; }
.vac-label-city::before {
  content: ""; position: absolute; left: -2px; top: -2px; width: 4px; height: 4px;
  border-radius: var(--radius-full); background: var(--text-secondary);
}

/* Pins: a round chip with the destination's emoji. */
.vac-pin-icon { background: none; border: 0; }
.vac-pin-icon:focus-visible { outline: none; }
.vac-pin {
  position: relative; display: grid; place-items: center; width: 36px; height: 36px;
  border-radius: var(--radius-full); background: var(--band-start); border: 2px solid var(--text-primary);
  box-shadow: 0 2px 8px var(--vac-shadow, var(--ground));
  font-size: 18px; line-height: 1; cursor: pointer;
  transition: transform var(--motion-fast), background var(--motion-fast);
}
/* No emoji: the chip still reads as a place. */
.vac-pin.is-plain::before {
  content: ""; width: 8px; height: 8px; border-radius: var(--radius-full); background: var(--text-primary);
}
.vac-pin.is-partner { border-color: var(--accent-attention); box-shadow: 0 0 0 2px var(--accent-attention), 0 2px 8px var(--ground); }
.vac-pin-star {
  position: absolute; top: -7px; right: -7px; width: 18px; height: 18px; display: grid; place-items: center;
  border-radius: var(--radius-full); background: var(--accent-attention); color: var(--ground);
  border: 1px solid var(--ground); font-size: 11px; line-height: 1;
}
/* Zoomed far out the chips shrink, so a region full of them stays readable. */
.vac-far .vac-pin { transform: scale(0.72); }
.vac-pin-icon:hover .vac-pin,
.vac-pin-icon:focus-visible .vac-pin,
.vac-pin-icon.is-hot .vac-pin,
.vac-pin-icon.is-active .vac-pin { transform: scale(1.2); background: var(--border-selected); }
.vac-pin-icon:focus-visible .vac-pin { outline: 2px solid var(--border-selected); outline-offset: 3px; }

.vac-home {
  display: grid; place-items: center; width: 32px; height: 32px; border-radius: var(--radius-full);
  background: var(--accent-positive); border: 2px solid var(--text-primary); color: var(--text-primary);
  box-shadow: 0 2px 8px var(--ground);
}
.vac-home svg { width: 16px; height: 16px; }

/* Popup */
.map-pane .leaflet-popup-content-wrapper {
  background: var(--vac-solid-card); color: var(--text-primary);
  border: 1px solid var(--border-default); border-radius: var(--radius-lg);
  box-shadow: 0 8px 24px var(--vac-shadow);
}
.map-pane .leaflet-popup-tip {
  background: var(--vac-solid-card); border: 1px solid var(--border-default); box-shadow: none;
}
.map-pane .leaflet-popup-content {
  margin: var(--space-lg); font-size: var(--type-caption-size); line-height: var(--type-caption-line);
}
.map-pane .leaflet-container a.leaflet-popup-close-button {
  top: var(--space-xs); right: var(--space-xs); width: 32px; height: 32px;
  font: 22px/32px var(--font-family); color: var(--text-secondary);
}
.map-pane .leaflet-container a.leaflet-popup-close-button:hover { color: var(--text-primary); }
.vac-pop { display: flex; flex-direction: column; gap: var(--space-xs); min-width: 180px; }
.vac-pop-title {
  padding-right: var(--space-xl); font-size: var(--type-emphasis-size); line-height: var(--type-emphasis-line);
  font-weight: 700; overflow-wrap: anywhere;
}
.vac-pop-place { overflow-wrap: anywhere; }
.vac-pop-ad {
  margin-top: var(--space-sm); font-size: var(--type-micro-size); line-height: var(--type-micro-line);
  font-weight: 700; letter-spacing: var(--tracking-micro);
}
.map-pane .leaflet-container a.vac-pop-go { margin-top: var(--space-sm); color: var(--text-on-accent); }
.vac-pop-ad + .vac-pop-go { margin-top: var(--space-xs); }

/* Zoom buttons and the credit */
.map-pane .leaflet-bar {
  border: 1px solid var(--border-default); border-radius: var(--radius-sm); overflow: hidden;
  box-shadow: 0 8px 24px var(--vac-shadow);
}
.map-pane .leaflet-bar a,
.map-pane .leaflet-touch .leaflet-bar a {
  width: 40px; height: 40px; line-height: 40px; font-size: 20px;
  background: var(--vac-solid-card); color: var(--text-primary); border-bottom: 1px solid var(--border-subtle);
}
.map-pane .leaflet-bar a:last-child { border-bottom: 0; }
.map-pane .leaflet-bar a:hover,
.map-pane .leaflet-bar a:focus-visible { background: var(--vac-solid-raised); color: var(--text-primary); }
.map-pane .leaflet-bar a.leaflet-disabled { background: var(--vac-solid-card); color: var(--border-default); cursor: default; }
.map-pane .leaflet-touch .leaflet-bar { border: 1px solid var(--border-default); }
.map-pane .leaflet-container .leaflet-control-attribution {
  margin: 0; padding: var(--space-xxs) var(--space-sm); border-top-left-radius: var(--radius-xs);
  background: var(--vac-shadow); color: var(--text-secondary);
  font-size: var(--type-micro-size); line-height: var(--type-micro-line);
}

/* ── Without JavaScript ────────────────────────────────────────────────── */

/* The list is the page. Nothing that needs the script takes up room. */
@media (scripting: none) {
  .plz, .map-pane, .map-toggle { display: none !important; }
  .split { display: block !important; }
}
