/* map — page styles. Tokens and shared components only (see docs/DESIGN.md §3.6).
   The map itself is game art and looks the same in both themes (raw colours below are part of
   that art). Its toolbar, legend, quiz banner and region panel are shared components floating on
   it, so they follow the theme. */
@layer pages {

  /* ── The stage ──
     Strokes and labels are sized as `Npx / (--u * --k)` so they stay N screen pixels at every zoom:
     --k is the zoom of the inner camera group, --u the px size of one map unit.
     Country colours (--c0…--c11) and the sea and land tones are tokens (tokens.css). */
  /* The map fills the screen under the top bar (60px and its 1px hairline, nav.css). */
  .map-page { --map-none: #5a6274; --map-gap: var(--sp-4);
    position: relative; height: calc(100vh - 61px); height: calc(100dvh - 61px - env(safe-area-inset-top, 0px)); overflow: hidden;
    background: radial-gradient(ellipse at 50% 40%, #13203a, var(--map-sea) 70%); }
  .map-frame { position: absolute; inset: 0; overflow: hidden; cursor: grab; touch-action: none; user-select: none; }
  .map-frame:active { cursor: grabbing; }
  /* While dragging, the regions sliding under the pointer must not light up and fade: that shimmer was the flicker. */
  .map-frame.dragging .map-svg * { pointer-events: none; transition: none; }
  .map-loading { position: absolute; inset: 0; display: grid; place-items: center; }
  .map-svg { position: absolute; left: 0; top: 0; width: 100%; height: auto; transform-origin: 0 0; overflow: visible; }
  .map-svg .land path { fill: var(--map-land); }
  /* Highlights lighten the fill instead of using `filter`, which re-rasterises the shape at low resolution (blurry) once zoomed. */
  .map-svg .region { fill: var(--fill); stroke: rgba(11, 18, 32, .5); stroke-width: .7px; vector-effect: non-scaling-stroke; cursor: pointer; transition: fill var(--t-base), opacity var(--t-base); }
  .map-svg .region:hover { fill: color-mix(in srgb, var(--fill) 85%, white); }
  .map-svg .region.sel { fill: color-mix(in srgb, var(--fill) 88%, white); stroke: var(--brand); stroke-width: 2.5px; }
  .map-svg .region.dim { opacity: .18; }
  .map-svg .borders path { fill: none; stroke: rgba(11, 18, 32, .9); stroke-width: 1.6px; vector-effect: non-scaling-stroke; pointer-events: none; }
  .map-svg text { text-rendering: geometricPrecision; pointer-events: none; text-anchor: middle; dominant-baseline: middle; font-family: var(--font-ui); paint-order: stroke; stroke: rgba(11, 18, 32, .75); stroke-linejoin: round; }
  /* Country names read like signage on a war-room map: Barlow Condensed, spaced capitals. */
  .map-svg .clabel { display: none; font-family: var(--font-display); font-weight: var(--fw-bold); letter-spacing: .08em; text-transform: uppercase; fill: rgba(16, 22, 34, .85); stroke: rgba(255, 255, 255, .25);
    font-size: calc(var(--fs) * 1.12px / max(1, var(--k) * .55)); stroke-width: calc(1px / (var(--u) * var(--k))); }
  .map-svg .clabel.on { display: inline; }
  .map-svg .rlabel { display: none; opacity: .95; font-weight: var(--fw-semibold); fill: #f2f5fb; font-size: calc(11px / (var(--u) * var(--k))); stroke-width: calc(3px / (var(--u) * var(--k))); }
  .map-svg .rlabel.on { display: inline; }
  .map-svg .capital { fill: #fff3b0; font-size: calc(10px / (var(--u) * var(--k))); stroke-width: calc(2.5px / (var(--u) * var(--k))); }
  .map-svg .you circle { fill: var(--brand); stroke: #231c00; stroke-width: .5; transform: scale(calc(1 / (var(--u) * var(--k)))); }
  .map-svg .you .pulse { fill: color-mix(in srgb, var(--brand) 35%, transparent); animation: you-pulse 1.8s ease-out infinite; }
  @keyframes you-pulse { from { opacity: 1; } to { opacity: 0; r: 14; } }
  .map-overlay { pointer-events: none; }

  /* Satellite: the Earth from orbit (assets/map/, scripts/draw_satellite.py) hanging in deep space,
     with an atmosphere, limb darkening and a slow cloud deck that thins as you zoom in. Owners are a
     light tint over the real ground and borders fine white lines, like a navigation overlay on a
     photograph, so the planet stays the hero. */
  .map-page.sat { background: radial-gradient(ellipse at 50% 45%, #0a1528 0%, #050a16 45%, var(--space) 100%); }
  .map-page.sat::before { content: ""; position: absolute; inset: 0; pointer-events: none; opacity: .75;
    background-image:
      radial-gradient(1px 1px at 23px 41px, #fff 50%, transparent 51%),
      radial-gradient(1px 1px at 117px 173px, rgba(255, 255, 255, .8) 50%, transparent 51%),
      radial-gradient(1.5px 1.5px at 201px 77px, rgba(200, 222, 255, .9) 50%, transparent 51%),
      radial-gradient(1px 1px at 61px 229px, rgba(255, 255, 255, .55) 50%, transparent 51%),
      radial-gradient(1px 1px at 157px 11px, rgba(255, 240, 220, .7) 50%, transparent 51%),
      radial-gradient(1.5px 1.5px at 311px 263px, rgba(255, 255, 255, .85) 50%, transparent 51%),
      radial-gradient(1px 1px at 283px 131px, rgba(255, 255, 255, .5) 50%, transparent 51%);
    background-size: 260px 260px, 260px 260px, 340px 340px, 300px 300px, 220px 220px, 410px 410px, 370px 370px; }
  .map-page.sat .map-frame::after { content: ""; position: absolute; inset: 0; pointer-events: none;
    background: radial-gradient(ellipse at 50% 50%, transparent 62%, rgba(0, 0, 0, .42)); }
  .map-svg .globe-light { pointer-events: none; }
  .map-svg .globe-back .ocean { fill: var(--map-ocean); }
  .map-svg .atm { fill: none; stroke: var(--atmo); }
  .map-svg .atm.a0 { stroke-width: 3; stroke-opacity: .5; }
  .map-svg .atm.a1 { stroke-width: 7; stroke-opacity: .2; }
  .map-svg .atm.a2 { stroke-width: 14; stroke-opacity: .09; }
  .map-svg .atm.a3 { stroke-width: 26; stroke-opacity: .04; }
  .map-svg .globe-light .rim { fill: none; stroke: rgba(150, 205, 255, .5); stroke-width: 6; }
  .map-page.sat .map-svg .land path { display: none; }
  .map-page.sat .map-svg .region { fill-opacity: .2; stroke: rgba(255, 255, 255, .13); stroke-width: .6px; transition: fill-opacity var(--t-fast), opacity var(--t-base); }
  .map-page.sat .map-svg .region:hover { fill-opacity: .4; }
  .map-page.sat .map-svg .region.sel { fill-opacity: .42; stroke: var(--brand); stroke-width: calc(2.5px / (var(--u) * var(--k))); }
  .map-page.sat .map-svg .region.dim { opacity: 1; fill: var(--space); fill-opacity: .62; }
  .map-page.sat .map-svg .borders path { stroke: rgba(235, 242, 255, .6); stroke-width: calc(1.1px / (var(--u) * var(--k))); }
  .map-page.sat .map-svg text { stroke: rgba(2, 6, 16, .62); }
  .map-page.sat .map-svg .clabel { fill: rgba(255, 255, 255, .92); stroke-width: calc(2.6px / (var(--u) * var(--k))); }
  /* The cloud deck: HTML, moved with the camera by map.rs and masked to the globe. Each deck is a
     strip two tiles wide sliding one tile east, forever; the high cirrus moves faster than the low
     weather, which reads as depth. */
  .map-clouds { position: absolute; left: 0; top: 0; transform-origin: 0 0; pointer-events: none; will-change: transform, opacity; }
  .map-clouds-mask { position: absolute; inset: 0;
    -webkit-mask-size: 100% 100%; mask-size: 100% 100%; -webkit-mask-repeat: no-repeat; mask-repeat: no-repeat; }
  .cloud-deck { position: absolute; inset: 0; overflow: hidden; }
  .cloud-deck > div { position: absolute; top: 0; left: -100%; width: 200%; height: 100%;
    background: url("../../assets/map/clouds_low.webp") 0 0 / 50% 100% repeat-x; animation: cloud-drift 900s linear infinite; }
  .cloud-deck.high > div { background-image: url("../../assets/map/clouds_high.webp"); animation-duration: 520s; opacity: .8; }
  @keyframes cloud-drift { to { transform: translateX(50%); } }

  /* ── Floating chrome: shared components (.card, .tabs, select, .btn, .stats, .chip, .pill) ── */
  .map-toolbar, .map-legend, .map-panel { position: absolute; box-shadow: var(--shadow-2), var(--highlight); }

  /* Toolbar: map style, the two filters and the zoom, in one row. */
  .map-toolbar { left: var(--map-gap); top: var(--map-gap); z-index: 3; display: flex; align-items: center; gap: var(--sp-2); padding: var(--sp-1); max-width: calc(100% - 2 * var(--map-gap)); }
  .map-filters { display: flex; gap: var(--sp-2); min-width: 0; }
  .map-filters select { width: 180px; }
  .map-country { width: 200px; }
  .map-zoom-level { min-width: 4.2ch; padding: 0 var(--sp-1); text-align: center; font-size: var(--fs-sm); font-weight: var(--fw-semibold); color: var(--text-2); font-variant-numeric: tabular-nums; user-select: none; }
  .map-zoom { display: flex; align-items: center; gap: 2px; padding-left: var(--sp-1); border-left: 1px solid var(--border-subtle); }

  /* Legend: what the marks on the map mean. */
  .map-legend { left: var(--map-gap); bottom: var(--map-gap); z-index: 2; display: flex; align-items: center; gap: var(--sp-4); padding: var(--sp-2) var(--sp-4); }
  .map-key { display: inline-flex; align-items: center; gap: var(--sp-2); white-space: nowrap; font-size: var(--fs-sm); font-weight: var(--fw-medium); color: var(--text-2); }
  .map-key i { display: inline-grid; place-items: center; flex: none; font-style: normal; }
  .key-you { width: 10px; height: 10px; border-radius: 50%; background: var(--brand); box-shadow: 0 0 0 3px color-mix(in srgb, var(--brand) 30%, transparent); }
  .key-capital { width: 12px; color: var(--gold-text); font-size: var(--fs-sm); line-height: 1; }
  .map-key .icon { color: var(--text-3); }

  /* The region panel: who holds it, what it is rich in, and travel. */
  .map-panel { right: var(--map-gap); top: var(--map-gap); z-index: 4; width: 360px; max-height: calc(100% - 2 * var(--map-gap)); overflow: auto; overscroll-behavior: contain;
    display: flex; flex-direction: column; gap: var(--sp-4); padding: var(--sp-5); box-shadow: var(--shadow-3), var(--highlight); animation: page-in var(--t-slow) var(--ease); }
  .map-panel-head { display: flex; justify-content: space-between; align-items: flex-start; gap: var(--sp-3); }
  .map-panel-head h2 { margin-top: 2px; overflow-wrap: anywhere; }
  .map-panel-tools { display: flex; gap: 2px; margin: calc(-1 * var(--sp-1)) calc(-1 * var(--sp-2)) 0 0; }
  .map-owner { display: inline-flex; align-items: center; gap: var(--sp-2); align-self: flex-start; margin-top: calc(-1 * var(--sp-2)); font-weight: var(--fw-semibold); }
  .map-owner .icon { color: var(--text-3); transition: transform var(--t-fast) var(--ease); }
  .map-owner:hover .icon { color: var(--brand-text); transform: translateX(2px); }
  /* The campaign being fought for the region: who attacks whom, the round score, and a link to it. */
  .map-campaign { display: flex; flex-direction: column; gap: var(--sp-2); padding: var(--sp-3); border-radius: var(--r-md); color: var(--text);
    background: var(--red-soft); border: 1px solid color-mix(in srgb, var(--red) 30%, transparent); transition: border-color var(--t-fast), background-color var(--t-fast); }
  .map-campaign:hover { border-color: var(--red); }
  .map-campaign .t-overline { display: inline-flex; align-items: center; gap: var(--sp-2); color: var(--red-text); }
  .map-campaign .live-dot { width: 8px; height: 8px; border-radius: 50%; background: var(--red); }
  .map-campaign-sides { display: flex; align-items: center; justify-content: space-between; gap: var(--sp-2); font-weight: var(--fw-semibold); }
  .map-campaign-sides .place-cell { display: inline-flex; align-items: center; gap: var(--sp-2); min-width: 0; }
  .map-campaign-go { display: inline-flex; align-items: center; gap: var(--sp-1); align-self: flex-end; font-size: var(--fs-sm); color: var(--text-2); }
  .map-campaign:hover .map-campaign-go { color: var(--brand-text); }
  .map-stats { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .map-actions { display: flex; flex-wrap: wrap; align-items: center; gap: var(--sp-2); padding-top: var(--sp-4); border-top: 1px solid var(--border-subtle); }

  /* Narrower desktops: the panel opens under the toolbar; the legend gives way to the quiz banner
     (quiz.css). */
  @media (max-width: 1180px) {
    .map-panel { top: calc(var(--map-gap) + 64px); max-height: calc(100% - 64px - 2 * var(--map-gap)); }
    .quiz-banner ~ .map-legend { display: none; }
  }
  /* Tablets and phones: the toolbar spans the top in two rows, the panel is a sheet at the bottom. */
  @media (max-width: 860px) {
    .map-page { --map-gap: var(--sp-3); }
    .map-toolbar { right: var(--map-gap); display: grid; grid-template-columns: minmax(0, 1fr) auto; }
    .map-toolbar .tabs { width: 100%; }
    .map-filters { grid-column: 1 / -1; grid-row: 2; }
    .map-filters select { flex: 1; width: auto; }
    .map-country { flex: 1; width: auto; }
    .map-legend { display: none; }
    .map-panel { left: var(--map-gap); right: var(--map-gap); top: auto; bottom: var(--map-gap); width: auto; max-height: 58%; padding: var(--sp-4); gap: var(--sp-3); }
  }
  /* Phones: the map ends above the bottom tab bar (nav.css): 56px top bar, the tab bar, a hairline each. */
  @media (max-width: 720px) {
    .map-page { height: calc(100vh - 58px - var(--tabbar-h));
      height: calc(100dvh - 58px - var(--tabbar-h) - env(safe-area-inset-bottom, 0px) - env(safe-area-inset-top, 0px)); }
    /* The map already ends above the tab bar, so its banner sits on the map's own edge. */
    .map-page .quiz-banner { bottom: var(--map-gap); }
  }
  @media (max-width: 560px) {
    .map-toolbar .tab .icon { display: none; }
  }
  @media (prefers-reduced-motion: reduce) {
    .map-svg .you .pulse, .cloud-deck > div { animation: none; }
  }
}
