/* =========================================================================
   THE CARD POPUP — its own file.

   It was inside chapter.css, which was right while only chapter pages opened
   one. The list beside the constellation on the FRONT page opens the same
   panel now, and the front page has no business loading the whole chapter
   stylesheet to get one component. So the component moved out; both pages
   link this, and there is still exactly one popup on the site.

   Portrait panel: pictures on top, then the words, which scroll on their own
   when there are a lot of them. Two ways out and no others — the round X, or
   anywhere outside the panel.
   ========================================================================= */
.pop {
  position:fixed; inset:0; z-index:200; display:grid; place-items:center;
  padding:clamp(0.8rem,3vw,2rem); opacity:0; transition:opacity 0.24s ease;
}
.pop.is-open { opacity:1; }
.pop[hidden] { display:none; }
.pop__scrim {
  position:absolute; inset:0; cursor:pointer;
  background:color-mix(in srgb, var(--black) 55%, transparent); backdrop-filter:blur(14px);
}
.pop__panel {
  position:relative; width:min(30rem,94vw); max-height:min(88vh,52rem);
  display:flex; flex-direction:column; overflow:hidden;
  background:var(--white); color:var(--black); border-radius:26px;
  box-shadow:0 50px 110px -30px rgba(0,0,0,0.7);
  transform:scale(0.94) translateY(12px);
  transition:transform 0.3s cubic-bezier(0.2,0.9,0.3,1.2);
}
.pop.is-open .pop__panel { transform:none; }

.pop__x {
  position:absolute; top:0.85rem; right:0.85rem; z-index:3;
  width:2.1rem; height:2.1rem; border-radius:50%; border:0; cursor:pointer;
  background:color-mix(in srgb, var(--black) 45%, transparent); color:var(--white);
  font-size:1.25rem; line-height:1; display:grid; place-items:center;
  backdrop-filter:blur(6px);
  transition:background 0.18s ease, transform 0.18s ease;
}
.pop__x:hover { background:var(--black); transform:scale(1.08); }

/* the pictures */
.pop__media { position:relative; flex:none; aspect-ratio:4/3; overflow:hidden; background:#101018; }
.pop__media[hidden] { display:none; }
.pop__slides { display:flex; height:100%; transition:transform 0.5s cubic-bezier(0.3,0.9,0.3,1); }
.pop__slide { flex:none; width:100%; height:100%; margin:0; }
/* THE WHOLE PICTURE, NOT A CROP OF IT.
   `cover` filled the box by cutting the picture, which is right for a card on
   a ring — the card is a thumbnail and a crop of a photograph still reads.
   It is wrong HERE. This panel is where somebody has pressed BECAUSE they
   wanted to see the picture, and half of what they open is a logo, a goal
   badge or a screen grab with words on it. Cropping those takes the words
   off: the SDG badges opened with their own numbers cut in half.
   `contain` on a neutral ground shows all of it, always. A photograph gets a
   little air at the sides, which reads as deliberate; a badge stays a badge. */
.pop__slide img { width:100%; height:100%; object-fit:contain; display:block; }
.pop__dots {
  position:absolute; left:50%; bottom:0.7rem; transform:translateX(-50%);
  display:flex; gap:0.4rem; padding:0.35rem 0.6rem; border-radius:999px;
  background:color-mix(in srgb, var(--black) 38%, transparent); backdrop-filter:blur(6px);
}
.pop__dots[hidden] { display:none; }
.pop__dots i {
  width:0.42rem; height:0.42rem; border-radius:50%; cursor:pointer;
  background:rgba(255,255,255,0.45); transition:background 0.2s ease, transform 0.2s ease;
}
.pop__dots i.is-on { background:var(--white); transform:scale(1.25); }

/* The picture above is cropped to a 4:3 box. This opens the whole one, at its
   own size, in a tab of its own. Bottom right, so it clears the round X above
   it and the dots in the middle. */
.pop__view {
  position:absolute; right:0.7rem; bottom:0.7rem; z-index:3;
  padding:0.35rem 0.7rem; border-radius:999px;
  font-size:0.72rem; font-weight:700; letter-spacing:0.02em; line-height:1;
  color:var(--white); text-decoration:none; white-space:nowrap;
  background:color-mix(in srgb, var(--black) 45%, transparent);
  backdrop-filter:blur(6px);
  /* the band is clipped to the pill */
  overflow:hidden;
  transition:background 0.18s ease, transform 0.18s ease;
  /* a slow breath of light around it, so it is findable on a busy photograph
     even in the four seconds between sweeps */
  animation:pop-view-glow 3.4s ease-in-out infinite;
}
.pop__view[hidden] { display:none; }
.pop__view:hover { background:var(--black); transform:translateY(-1px); }
.pop__view:focus-visible { outline:2px solid var(--white); outline-offset:2px; }

/* THE SWEEP. Same idiom as the cards on the rest of the site — a narrow
   diagonal band, moving for about a second of a three-and-a-bit second cycle,
   so most of the time nothing is moving and it never becomes noise.
   Its own keyframes rather than shine.css's, because this button lives inside
   a panel that is display:none until it is opened, and the script that hands
   out the site's shine measures where things sit on the page. It cannot
   measure something that is not there yet. */
/* MEASURED IN PIXELS, ON A BOX THAT FILLS THE PILL.
   Two earlier attempts failed the same way and both looked right in the
   computed styles. One animated background-position against a gradient sized
   240% of the box; the other positioned a skewed bar with percentage offsets.
   In each the bright part sat outside the pill for the whole sweep and
   nothing ever appeared on screen.
   What settled it was painting the pseudo-element solid red: it filled the
   pill, so it was never a question of whether it drew — only of where the
   light was. So: a box that covers the pill exactly, a 70-pixel band inside
   it, and a position in PIXELS, which cannot be misread. */
.pop__view::after {
  content:''; position:absolute; inset:0; border-radius:inherit;
  pointer-events:none;
  background-image:linear-gradient(100deg,
    rgba(255,255,255,0) 0%,
    rgba(255,255,255,0.18) 35%,
    rgba(255,255,255,0.68) 50%,
    rgba(255,255,255,0.18) 65%,
    rgba(255,255,255,0) 100%);
  background-repeat:no-repeat;
  background-size:58px 100%;
  background-position-x:-80px;
  animation:pop-view-shine 3.4s ease-in-out infinite;
}
/* It travels for about a second of the three and a bit, then waits — most of
   the time nothing is moving, which is what keeps it from being noise. */
@keyframes pop-view-shine {
  0%, 8%     { background-position-x:-80px; }
  34%, 100%  { background-position-x:230px; }
}
@keyframes pop-view-glow {
  0%, 100% { box-shadow:0 0 0 0 rgba(255,255,255,0); }
  30%      { box-shadow:0 0 14px 1px rgba(255,255,255,0.5); }
}
/* once it has been found it stops asking to be found */
.pop__view:hover, .pop__view:focus-visible { animation:none; }
.pop__view:hover::after, .pop__view:focus-visible::after { animation:none; opacity:0; }

/* the words — this is the part that scrolls */
.pop__scroll { overflow-y:auto; padding:1.4rem 1.5rem 1.6rem; -webkit-overflow-scrolling:touch; }
.pop__kicker {
  font-size:0.7rem; font-weight:700; letter-spacing:0.1em; text-transform:uppercase;
  color:var(--blue); margin-bottom:0.4rem;
}
.pop__title { font-size:1.4rem; font-weight:700; letter-spacing:-0.02em; line-height:1.2; }
.pop__sub { font-size:0.95rem; color:#3a3a3e; margin-top:0.35rem; }
.pop__meta { font-size:0.78rem; color:#86868b; margin-top:0.5rem; }
.pop__text { margin-top:0.9rem; }
.pop__text p { font-size:0.94rem; line-height:1.6; color:#3a3a3e; }
.pop__text p + p { margin-top:0.8rem; }
/* an address inside a story. It has to break, or one long one pushes the
   panel wider than the phone it is being read on */
.pop__link {
  color:var(--blue); font-weight:600; text-decoration:underline;
  text-underline-offset:2px; overflow-wrap:anywhere;
}
.pop__link:hover { color:var(--black); }
.pop__go {
  display:inline-block; margin-top:1.1rem; font-size:0.9rem; font-weight:700;
  color:var(--blue); text-decoration:none;
}
/* THE RULE ITS THREE SIBLINGS ALL HAD AND THIS ONE DID NOT.
   `hidden` is only `display:none` from the browser's own stylesheet, so the
   `display:inline-block` above beat it and the link never went away. A card
   with no address showed the PREVIOUS card's words — MANUF4.0 offering
   "Visit the project →", pointing nowhere, because FLINKEN had been opened
   before it. Every other part of this panel is toggled the same way and every
   other one carries this line. */
.pop__go[hidden] { display:none; }
.pop__go:hover { text-decoration:underline; }

@media (prefers-reduced-motion:reduce) {
  .pop, .pop__panel, .pop__slides { transition:none; }
  /* Somebody who has asked their computer for less movement has asked for
     this too. The button is still there and still says what it does. */
  .pop__view { animation:none; }
  .pop__view::after { animation:none; opacity:0; }
}

