/* ============================================================
   The map — layout only. Tokens, typography and shared chrome
   come from atlas.css, which every IGRED product loads first.
   ============================================================ */

/* ---------- stage: the monument ------------------------------ */

.stage {
  display: grid;
  grid-template-columns: 1fr;
  padding: clamp(16px, 3.5vw, 40px) var(--gutter) 0;
  gap: var(--rail-gap);
}

.rail { display: flex; flex-direction: column; gap: clamp(14px, 2.2vw, 26px); min-width: 0; }
/* ---------- time window: text, not pills --------------------- */

.window { display: flex; gap: clamp(14px, 2vw, 26px); align-items: baseline; }

.window-option {
  font: inherit; font-size: 11px; letter-spacing: 0.18em; text-transform: uppercase;
  color: var(--fg-2); background: none; border: 0; padding: 3px 0; cursor: pointer;
  border-bottom: 1px solid transparent;
}
.window-option:hover { color: var(--fg); }
.window-option.is-on { color: var(--fg); border-bottom-color: var(--fg); }

/* ---------- detail: revealed only on selection --------------- */

.detail { min-height: 108px; padding-top: 16px; border-top: 1px solid var(--hair); }

.detail .prompt { margin: 0; font-size: 11px; letter-spacing: 0.2em; text-transform: uppercase; color: var(--fg-2); }

.detail-place {
  font-family: var(--display);
  font-weight: 400;
  font-size: clamp(23px, 2.9vw, 38px); line-height: 1.1; letter-spacing: -0.018em;
  margin: 0 0 10px; text-wrap: balance;
  font-optical-sizing: auto;
}

.detail-meta { display: flex; flex-wrap: wrap; gap: 3px 22px; font-size: 11.5px; letter-spacing: 0.12em; text-transform: uppercase; }
.detail-meta .vmark { color: var(--verified); }
.detail-sources { margin: 12px 0 0; padding: 0; list-style: none; display: grid; gap: 5px; }
.detail-sources li { font-size: 12.5px; line-height: 1.5; }
.detail-sources a { color: var(--fg); text-underline-offset: 3px; }
.detail-sources .outlet { color: var(--fg-2); }

/* ---------- plate: the map ----------------------------------- */

.plate { position: relative; display: flex; flex-direction: column; min-width: 0; }

.plate svg { display: block; width: 100%; height: auto; touch-action: none; cursor: grab; }
.plate svg.is-panning { cursor: grabbing; }

.plate-tools {
  display: flex; gap: 16px; align-items: baseline; justify-content: flex-end;
  margin-top: 8px;
}
.plate-tools .link-button { min-width: 22px; text-align: center; }

.scale-key {
  display: flex; flex-wrap: wrap; align-items: center; gap: 6px 18px;
  margin: 10px 0 0; padding-top: 10px; border-top: 1px solid var(--hair-soft);
  font-size: 10.5px; letter-spacing: 0.14em; text-transform: uppercase; color: var(--fg-2);
}
.scale-key .swatch { display: inline-block; border-radius: 50%; margin-right: 6px; vertical-align: -1px; }
.scale-key .item { display: inline-flex; align-items: center; color: var(--fg); }

.heat circle { pointer-events: none; }
.scale-key .heat-swatch { background: var(--heat); opacity: 0.75; }
.heat-note { margin: 0; max-width: 78ch; }

.land-fill { fill: url(#stipple); }
.land-line { fill: none; stroke: var(--coast); stroke-width: 0.45; }

.evt { cursor: pointer; }
/* The hit target must never intercept a pan gesture's visual feedback, only clicks. */
.evt .hit { pointer-events: all; }
.evt circle { transition: opacity 380ms ease; }
.plate.dimmed .evt:not(.selected) { opacity: 0.1; }
.evt.selected .halo, .evt:focus-visible .halo { opacity: 0.5 !important; }
.evt:focus-visible { outline: none; }

/* The stage measures itself against the viewport, so a visible banner has to come
   out of that budget or the map is pushed off the bottom. */
body:has(.banner:not([hidden])) .stage { min-height: calc(100svh - 46px); }

/* ---------- index -------------------------------------------- */

.index {
  margin: clamp(30px, 5vw, 64px) var(--gutter) 0;
  padding-top: 18px;
  border-top: 1px solid var(--hair);
}

.index h2 {
  font-size: 11px; letter-spacing: 0.24em; text-transform: uppercase; font-weight: 500;
  color: var(--fg-2); margin: 0 0 14px;
}

.index-grid { columns: 210px auto; column-gap: clamp(22px, 3vw, 42px); }

.index-grid button {
  display: flex; justify-content: space-between; align-items: baseline; gap: 12px;
  width: 100%; font: inherit; font-size: 13.5px; text-align: left;
  color: var(--fg); background: none; border: 0; border-bottom: 1px solid var(--hair-soft);
  padding: 7px 0; cursor: pointer; break-inside: avoid;
}
.index-grid button:hover { color: var(--s3); }
.index-grid .count { font-variant-numeric: tabular-nums; font-size: 11px; color: var(--fg-2); }
.index-grid .is-verified { color: var(--verified); }
/* ============================================================
   TABLET — the column widens and the top block splits in two,
   so the title stops being a full screen of its own.
   ============================================================ */

@media (min-width: 760px) {
  body { font-size: 15.5px; }

  .title { font-size: clamp(60px, 7.8vw, 92px); }

  /* The title stops being a screen of its own: it shares a line with the standfirst. */
  .rail {
    display: grid;
    grid-template-columns: minmax(0, 1.15fr) minmax(240px, 0.85fr);
    grid-template-areas:
      "masthead masthead"
      "title    stand"
      "window   window";
    align-items: end;
    column-gap: clamp(24px, 4vw, 48px);
  }
  .masthead { grid-area: masthead; }
  .title { grid-area: title; }
  .standfirst { grid-area: stand; }
  .window { grid-area: window; }
}

/* ============================================================
   DESKTOP — the monument proper: a wall label beside a plate,
   together filling the viewport. The label reads top-to-bottom;
   the map is the object you look at.
   ============================================================ */

@media (min-width: 1120px) {
  .stage {
    /* The plate spans both rows; the label sits above the caption in column one. */
    grid-template-columns: minmax(330px, 30%) minmax(0, 1fr);
    grid-template-rows: 1fr auto;
    grid-template-areas:
      "rail   plate"
      "detail plate";
    align-items: stretch;
    min-height: 100svh;
    padding-bottom: clamp(20px, 3vw, 36px);
    column-gap: clamp(32px, 4vw, 64px);
    row-gap: 0;
  }

  .rail { grid-area: rail; }
  .plate { grid-area: plate; }
  .detail { grid-area: detail; }

  /* Back to a single reading column — the two-up split was a tablet compromise.
     align-items must be reset explicitly: the tablet rule sets `end` for grid row
     alignment, and left in place it aligns these flex children to the right edge. */
  .rail {
    display: flex;
    grid-template-columns: none;
    grid-template-areas: none;
    justify-content: flex-start;
    align-items: stretch;
  }

  .rail, .detail { padding-right: clamp(12px, 1.5vw, 28px); border-right: 1px solid var(--hair-soft); }

  .title { font-size: clamp(64px, 5.8vw, 102px); }
  .standfirst { max-width: 38ch; }

  .plate { justify-content: center; }
  .plate svg { height: auto; max-height: calc(100svh - 190px); }
}

/* ============================================================
   LARGE — the plate keeps growing; the label stays readable and
   simply gets more air around it.
   ============================================================ */

@media (min-width: 1700px) {
  :root { --gutter: clamp(44px, 4vw, 88px); }

  .stage { grid-template-columns: minmax(400px, 26%) minmax(0, 1fr); }

  /* On a tall screen the label would otherwise sit at the top with a 500px void beneath
     it. Centring the block splits that air above and below, which composes. */
  .rail { justify-content: center; }

  .title { font-size: clamp(96px, 6vw, 132px); }
  .standfirst { font-size: 17px; max-width: 40ch; }
  body { font-size: 16px; }
  .index-grid { columns: 240px auto; }
}

@media (min-width: 2300px) {
  /* Past this width the map stops gaining from more pixels, so the whole
     composition centres rather than stretching to the bezels. */
  .stage, .index, .colophon, .banner { max-width: 2200px; margin-inline: auto; }
  .stage { padding-inline: var(--gutter); }
}

/* ============================================================
   SHORT LANDSCAPE — a phone on its side has almost no height, so
   the map leads and the label collapses beside it.
   ============================================================ */

@media (max-width: 1119px) and (max-height: 560px) and (orientation: landscape) {
  .stage {
    grid-template-columns: minmax(220px, 34%) minmax(0, 1fr);
    grid-template-rows: 1fr auto;
    grid-template-areas: "rail plate" "detail plate";
  }
  .rail { display: flex; grid-area: rail; grid-template-areas: none; grid-template-columns: none; }
  .plate { grid-area: plate; }
  .detail { grid-area: detail; min-height: 0; }
  .title { font-size: clamp(30px, 4.4vw, 44px); }
  .standfirst { display: none; }
}

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { animation: none !important; transition: none !important; }
}

@keyframes bloom {
  from { r: var(--r0); opacity: 0.5; }
  to   { r: calc(var(--r0) * 5); opacity: 0; }
}
.bloom { animation: bloom 2400ms ease-out; }
