.story-map {
  --map-indigo:#17345f;
  --map-graphite:#5f625f;
  --map-coral:#c96f61;
  --map-cream:#ead7b5;
  --map-brass:#b7873d;
  --map-ink:#243149;
}
.story-map,.story-map * { box-sizing:border-box; }
.story-map button { font:inherit; }
.map-test-stage {
  min-height:100vh; display:grid; place-items:center; padding:32px;
  background:
    radial-gradient(circle at 50% 70%,rgba(67,92,126,.3),transparent 38%),
    linear-gradient(155deg,#172b50,#091225 72%);
}
.map-test-copy { max-width:720px; text-align:center; }
.map-test-kicker { color:#d5a968; letter-spacing:.14em; text-transform:uppercase; font-size:12px; }
.map-test-copy h1 { margin:.25em 0; font-size:clamp(36px,7vw,80px); font-weight:400; }
.map-test-actions { display:flex; flex-wrap:wrap; justify-content:center; gap:12px; margin-top:26px; }
.map-test-actions button {
  border:1px solid rgba(231,205,151,.65); border-radius:999px; padding:11px 18px;
  color:#f8edd9; background:rgba(21,38,70,.82); cursor:pointer;
}

.story-map[hidden] { display:none; }
.story-map { position:fixed; inset:0; z-index:86; display:grid; place-items:center; visibility:hidden; color:#f6ead2; font-family:Georgia,"Times New Roman",serif; }
.story-map.is-open { visibility:visible; }
.story-map__scrim {
  position:absolute;
  inset:0;
  border:0;
  background:rgba(4,11,24,.77);
  -webkit-backdrop-filter:none;
  backdrop-filter:none;
  opacity:0;
  transition:opacity .28s ease;
}
.story-map.is-open .story-map__scrim { opacity:1; }
.story-map__stage { position:relative; width:min(96vw,1540px); max-height:100dvh; padding:56px 34px 40px; transform:translateY(22px) scale(.96); opacity:0; transition:transform .46s cubic-bezier(.18,.82,.22,1),opacity .28s ease; }
.story-map.is-open .story-map__stage { transform:none; opacity:1; }
.story-map__paper { position:relative; width:100%; transform-origin:50% 50%; filter:drop-shadow(0 28px 42px rgba(0,0,0,.42)); }
.story-map__paper > img { display:block; width:100%; height:auto; user-select:none; pointer-events:none; }

/* Mobile Story Mode rotates a portrait browser into an 844×390 logical
   landscape. `vw` still describes the physical portrait viewport there, so
   fit the 1672:941 manuscript against the logical stage height explicitly. */
html.is-mobile-storymode .story-map__stage {
  --mobile-map-scale:.43;
  /* Preserve the desktop manuscript as one 1672px composition, then scale
     the entire package. Individual vw-based labels previously reflowed at the
     phone viewport and destroyed the map's authored relationships. */
  position:absolute;
  left:50%;
  /* Anchor the authored composition to the true viewport centre. Offsetting
     this percentage compounds the transparent margins once the stage scales. */
  top:50%;
  translate:-50% -50%;
  width:1672px;
  max-width:none;
  max-height:none;
  padding:56px 34px 40px;
  transform:scale(var(--mobile-map-scale));
  transform-origin:50% 50%;
}
html.is-mobile-storymode .story-map.is-open .story-map__stage { transform:scale(var(--mobile-map-scale)); }
html.is-mobile-storymode .story-map__paper {
  width:100%;
  left:auto;
  translate:none;
}
html.is-mobile-storymode .story-map__close {
  position:absolute;
  top:18px;
  right:18px;
  translate:none;
}
html.is-mobile-storymode .story-map__hint,
html.is-mobile-storymode .story-map__live { margin-top:3px; font-size:22px; }
html.is-mobile-storymode .story-map__hint {
  position:relative;
  z-index:4;
  transform:translateY(-42px);
}
html.is-mobile-storymode .story-map__station-label { font-size:32px; }
html.is-mobile-storymode .story-map__station.is-current .story-map__station-label { font-size:38px; }
html.is-mobile-storymode .story-map__station-action { font-size:30px; }
html.is-mobile-storymode .story-map__plane { width:96px; }
.story-map__polaroid {
  --polaroid-rotate:-3.2deg;
  position:absolute; left:9.2%; top:50.5%; z-index:3;
  width:21%; aspect-ratio:1; margin:0; pointer-events:none;
  translate:-50% -50%; rotate:var(--polaroid-rotate);
  transform-origin:50% 18%;
  filter:drop-shadow(0 8px 8px rgba(67,45,30,.27));
}
.story-map__polaroid img { display:block; width:100%; height:100%; object-fit:contain; }
.story-map__polaroid.is-changing { animation:mapPolaroidChange .44s cubic-bezier(.2,.78,.22,1) both; }
.story-map__stations { position:absolute; inset:0; }
.story-map__station {
  position:absolute; left:var(--x); top:var(--y); width:13.2%; aspect-ratio:1.55;
  translate:-50% -50%; border:0; padding:0; color:var(--map-graphite); background:transparent;
  cursor:pointer; outline:none; isolation:isolate;
}
.story-map__station-ring {
  position:absolute; left:-32.5%; top:-18%; width:165%; height:220%; overflow:visible; pointer-events:none;
  object-fit:fill;
  opacity:0; transform:scale(.84) rotate(-1.5deg); transform-origin:50% 52%;
  transition:opacity .18s ease,transform .3s cubic-bezier(.2,.8,.2,1);
}
.story-map__station-mark {
  position:absolute; left:50%; top:47%; translate:-50% -50%; display:grid; place-items:center;
  width:104%; aspect-ratio:1; color:currentColor; transition:color .2s ease,transform .25s ease,width .25s ease;
}
.story-map__station-mark svg { width:100%; height:100%; fill:none; stroke:currentColor; stroke-width:1.8; stroke-linecap:round; stroke-linejoin:round; }
.story-map__station-mark img {
  display:block; width:100%; height:100%; object-fit:contain;
  filter:none;
}
.story-map__station-label {
  position:absolute; left:50%; top:99%; bottom:auto; translate:-50% 0; min-width:max-content; color:#41484b;
  font:400 clamp(21px,2vw,32px)/1.05 "HanziPen SC","HanziPenSC-W3","Kaiti SC","STKaiti","KaiTi","DFKai-SB","Songti SC","STSong","SimSun","Noto Serif CJK SC","PingFang SC","Microsoft YaHei",serif; letter-spacing:.015em;
  text-shadow:0 1px 0 rgba(255,248,226,.78);
}
.story-map__station-action {
  position:absolute; left:var(--go-x); top:var(--go-y); translate:-50% -50%; min-width:max-content;
  color:var(--map-coral); font:400 clamp(20px,1.85vw,32px)/1 "HanziPen SC","HanziPenSC-W3","Kaiti SC","STKaiti","KaiTi","DFKai-SB","Songti SC","STSong","SimSun","Noto Serif CJK SC","PingFang SC","Microsoft YaHei",serif;
  letter-spacing:.02em; opacity:0; transform:rotate(var(--go-rotate,0deg)) scale(.86);
  transition:opacity .18s ease,transform .25s cubic-bezier(.2,.8,.2,1);
}
.story-map.is-zh .story-map__station-label,
.story-map.is-zh .story-map__station-action {
  font-family:"HanziPen SC","HanziPenSC-W3","Kaiti SC","STKaiti","KaiTi","DFKai-SB","Songti SC","STSong","SimSun","Noto Serif CJK SC","PingFang SC","Microsoft YaHei",serif;
  font-weight:400;
  letter-spacing:.035em;
}
.story-map__station:hover .story-map__station-ring,.story-map__station:focus-visible .story-map__station-ring { opacity:.48; transform:scale(1) rotate(-1.5deg); }
.story-map__station:hover .story-map__station-mark,.story-map__station:focus-visible .story-map__station-mark { color:var(--map-indigo); transform:translateY(-2px); }
.story-map__station:hover .story-map__station-action,.story-map__station:focus-visible .story-map__station-action { opacity:1; transform:rotate(var(--go-rotate,0deg)) scale(1); }
.story-map__station.is-current .story-map__station-mark { color:var(--map-indigo); }
.story-map__station.is-current .story-map__station-mark { width:124%; }
.story-map__station.is-current .story-map__station-label { font-size:clamp(25px,2.4vw,38px); }
.story-map__station.is-current .story-map__station-ring { opacity:.94; transform:scale(1) rotate(-1.5deg); }
.story-map__station.is-current::after {
  content:""; position:absolute; left:50%; top:108%; width:18px; aspect-ratio:1; border-radius:2px 50% 50% 50%;
  translate:-50% -50%; rotate:45deg; background:var(--map-coral); box-shadow:0 2px 0 rgba(78,50,36,.2);
  display:none;
}
.story-map__station.is-current .story-map__station-action {
  display:none;
}
.story-map__station:disabled { cursor:not-allowed; opacity:.42; }
.story-map__station:disabled .story-map__station-action { color:#666; }
.story-map__plane {
  position:absolute; left:0; top:0; width:clamp(63px,5.1vw,96px); opacity:0; pointer-events:none; z-index:8;
  transform:translate(-50%,-50%) rotate(-7deg); transition:opacity .2s ease;
  filter:drop-shadow(0 6px 5px rgba(64,48,38,.27));
}
.story-map__plane img { display:block; width:100%; height:auto; transform:scaleX(var(--plane-direction,1)); transform-origin:50% 50%; }
.story-map__plane.is-parked,.story-map__plane.is-flying { opacity:1; }
.story-map__plane.is-parked { animation:mapPlaneHover 2.8s ease-in-out infinite; }
/* The panel close, shared. Geometry, glyph and motion are lifted from
   .dialog-close -- 34px, no border, 21px mark, rotate on hover -- so the
   Map, About and the chat machine's waiting panel all close with the same
   button the project panels use.

   Only the two colours are surfaced, because these three do not stand on
   the same thing. The panels sit on pale glass, where the panel's own
   teal-on-mint pair is exactly right; the Map and About sit on a near-black
   scrim, where that same pair would be a dark mark on a dark field. Same
   button, lit for the surface under it -- which is what matching means when
   the surfaces differ this much in luminance.

   It states its own type rather than inheriting it: the Map's used to sit
   inside .story-map and pick up Georgia while About's picked up Quicksand,
   so one × came out serif-thin and the other round-thick. Centring is flex,
   not line-height, for the same reason -- metric centring moves whenever the
   family under it changes. */
.story-map__close {
  --close-ink:#f4e7ce;
  --close-field:rgba(244,231,206,.14);
  --close-field-hover:rgba(244,231,206,.26);
  position:absolute; z-index:20; right:18px; top:18px;
  width:34px; height:34px; aspect-ratio:auto;
  display:flex; align-items:center; justify-content:center; padding:0;
  border:0; border-radius:50%;
  color:var(--close-ink); background:var(--close-field);
  font:400 21px/1 Quicksand,ui-rounded,system-ui,sans-serif;
  cursor:pointer;
  transform-origin:50% 50%;
  transition:transform 180ms cubic-bezier(.2,.8,.2,1),background-color 160ms ease;
}
/* Wins against `.story-map button { font:inherit }`, which is (0,1,1) and
   would otherwise take the whole font shorthand back. */
.story-map .story-map__close { font:400 21px/1 Quicksand,ui-rounded,system-ui,sans-serif; }
.story-map__close:hover,.story-map__close:focus-visible {
  transform:rotate(90deg);
  background:var(--close-field-hover);
}
.story-map__hint,.story-map__live { margin:10px 0 0; text-align:center; color:#ead9b9; font-size:14px; letter-spacing:.04em; }
.story-map__live { min-height:1.4em; color:#e3ae69; }
.story-map.is-travelling .story-map__station { pointer-events:none; }
.story-map.is-folding .story-map__paper { animation:mapPaperFold .52s cubic-bezier(.55,.03,.45,.98) forwards; }
.story-map.is-reduced-motion .story-map__plane { display:none; }
.story-map.is-reduced-motion .story-map__stage,
.story-map.is-reduced-motion .story-map__scrim,
.story-map.is-reduced-motion .story-map__paper,
.story-map.is-reduced-motion .story-map__station-ring,
.story-map.is-reduced-motion .story-map__station-mark,
.story-map.is-reduced-motion .story-map__station-action { animation-duration:.01ms!important; transition-duration:.01ms!important; }
.story-map.is-reduced-motion .story-map__close { transition-duration:.01ms!important; }
@keyframes mapPaperFold { 45% { transform:scaleX(.5) rotateX(8deg); } 100% { transform:scale(.03,.7); opacity:0; } }
@keyframes mapPlaneHover {
  0%,100% { transform:translate(-50%,-50%) rotate(-7deg); }
  50% { transform:translate(calc(-50% + 6px),calc(-50% - 7px)) rotate(-4.5deg); }
}
@keyframes mapPolaroidChange {
  0% { opacity:.18; transform:translateY(-9px) scale(.94); }
  100% { opacity:1; transform:none; }
}
@keyframes mapCurrentPinHover {
  0%,100% { translate:-50% calc(-50% - 3px); }
  50% { translate:-50% calc(-50% + 3px); }
}
@media (max-width:760px) {
  .story-map__stage { width:100vw; padding:62px 8px 44px; }
  .story-map__paper { width:100vw; left:50%; translate:-50% 0; }
  .story-map__station-label { font-size:clamp(11px,3.2vw,15px); }
  .story-map__station.is-current .story-map__station-label { font-size:clamp(13px,3.8vw,17px); }
  .story-map__close { right:14px; }
  .story-map__polaroid { width:21.5%; left:9.8%; }
}
@media (prefers-reduced-motion:reduce) {
  .story-map,.story-map *,.story-map *::before,.story-map *::after { scroll-behavior:auto!important; animation-duration:.01ms!important; transition-duration:.01ms!important; }
  .story-map__plane { display:none; }
}
