/* map-chrome.css — one vocabulary for everything that floats over the map,
   and the phone bottom sheet. Loaded by map-legacy.html after tokens.css.
   (2026-09-20 redesign; plan in the vault, 30-Projects/SDL-Map/.)

   Specificity note: export.js and map-i18n.js inject their own <style>
   blocks at runtime, AFTER this file, so plain class selectors here would
   lose. Rules that must win double the class (`.x.x`) or add `body`.
   Tokens only — colours, radii and spacing come from tokens.css / the
   :root block in map-legacy.html. No glass, no glow: that pass is separate. */

/* ---------- desktop: one surface, one radius, one size ------------------ */
@media (min-width: 901px) {
  /* map-i18n.js and export.js set several of these with !important at
     runtime; the doubled selectors plus !important here settle it. */
  body .sdl-fab.sdl-fab,
  body .wm-reopen.wm-reopen,
  body #sdl-clear-floating {
    width: 36px !important; height: 36px !important;
    border-radius: var(--r-soft, 8px) !important;
    /* Surfaces read the glass properties (glass.css) with the solid slab as fallback */
    background-color: var(--surface, var(--surface-overlay)) !important;
    background-image: var(--surface-image, none) !important;
    border: 1px solid var(--surface-edge, var(--rule)) !important;
    box-shadow: var(--surface-shadow, none) !important;
    backdrop-filter: var(--surface-blur, none) !important; -webkit-backdrop-filter: var(--surface-blur, none) !important;
    color: var(--ink-2) !important;
    opacity: 1 !important;
  }
  body .sdl-fab.sdl-fab:hover, body .wm-reopen.wm-reopen:hover, body #sdl-clear-floating:hover {
    color: var(--ink) !important; border-color: var(--ink-3) !important;
  }
  body .sdl-fab.sdl-fab svg, body .wm-reopen.wm-reopen svg, body #sdl-clear-floating svg { width: 18px !important; height: 18px !important; }
  /* 44 px pitch from the left edge: about · clear · export · data */
  body.embed-mode .wm-reopen.wm-reopen       { top: calc(16px + var(--shell-top, 0px)) !important; left: 16px !important; }
  body.embed-mode #sdl-clear-floating        { top: calc(16px + var(--shell-top, 0px)) !important; left: 60px !important; }
  body.embed-mode #sdl-export-floating.sdl-fab { top: calc(16px + var(--shell-top, 0px)) !important; left: 104px !important; }
  body.embed-mode #sdl-data-floating.sdl-fab   { top: calc(16px + var(--shell-top, 0px)) !important; left: 148px !important; }

  /* The zoom column speaks the same design as the top-left row: five
     separate 36 px squares on the one surface, not one box with dividers. */
  body .zoom-ctl.zoom-ctl { padding: 0; gap: 6px; top: calc(16px + var(--shell-top, 0px)); right: 16px; background: none !important; border: 0 !important; box-shadow: none !important; backdrop-filter: none !important; -webkit-backdrop-filter: none !important; }
  body .zoom-ctl.zoom-ctl button {
    width: 36px; height: 36px; border-radius: var(--r-soft, 8px);
    border: 1px solid var(--surface-edge, var(--rule));
    background-color: var(--surface, var(--surface-overlay)); background-image: var(--surface-image, none);
    -webkit-backdrop-filter: var(--surface-blur, none); backdrop-filter: var(--surface-blur, none);
    box-shadow: var(--surface-shadow, none); color: var(--ink-2);
  }
  body .zoom-ctl.zoom-ctl button + button { border-top: 1px solid var(--surface-edge, var(--rule)); }
  body .zoom-ctl.zoom-ctl button:hover { color: var(--ink); border-color: var(--ink-3); background-color: var(--surface, var(--surface-overlay)); }
  body .zoom-ctl.zoom-ctl button.active { color: var(--ink); border-color: var(--ink-3); background-color: var(--surface, var(--surface-overlay)); }
  body .zoom-ctl.zoom-ctl button svg { width: 18px; height: 18px; }
  /* Bottom-right: the collapsible-sidebar tabs sit at mid-height on the
     right edge, and a region column under the zoom stack ran into them. */
  /* Region column moves to the bottom-left (2026-09-21): the bottom-right
     corner belongs to the in-view panel, as on zhiyan. */
  body .region-nav.region-nav { top: auto; bottom: calc(16px + var(--shell-bottom, 0px)); right: auto; left: 16px; gap: 4px; }
  /* The right drawer ("Selected": entries matching the filters) is retired on
     desktop; the in-view panel lists what is on screen, filtered. */
  body aside.right, body #mob-selected { display: none !important; }
  /* Desktop in-view panel (map-mobile-sheet.js builds it). Same glass as the
     bars and the phone sheet; appears only when the viewport shows a subset
     or a filter is active; peek = count, open = list. */
  .dpanel {
    position: fixed; right: 16px; bottom: calc(16px + var(--shell-bottom, 0px)); z-index: 45;
    width: 330px; max-height: 60svh;
    /* Head at the BOTTOM, list growing upward: on hover the head stays under
       the pointer while the rows unfold above it. */
    display: grid; grid-template-rows: 1fr auto; align-content: end;
    border: 1px solid var(--surface-edge, var(--rule)); border-radius: 12px;
    color: var(--ink); font-family: var(--font-sans);
    opacity: 0; visibility: hidden; pointer-events: none;
    transform: translateY(8px) scale(0.985); transform-origin: 100% 100%;
    overflow: hidden;
    /* Keep the open panel below the zoom column: its five buttons end at
       --shell-top + 220 px; 12 px of air on top of that. */
    max-height: min(60svh, calc(100svh - var(--shell-top, 0px) - var(--shell-bottom, 0px) - 248px));
  }
  /* glass.css sets a transition list of its own on every .glass surface (colour,
     shadow, edge) at (0,2,0), which REPLACED the panel's and drawer's own
     transitions, so both snapped. These lists outrank it and include its
     properties. The unfold is slower and calmer than a control response. */
  .dpanel.glass.glass {
    transition: opacity var(--t-base, 200ms) var(--ease-standard, ease), transform var(--t-base, 200ms) var(--ease-standard, ease),
      grid-template-rows var(--t-unfold, 460ms) var(--ease-unfold, ease), visibility 0s linear var(--t-base, 200ms),
      background-color var(--t-base, 200ms) var(--ease-standard, ease), box-shadow var(--t-base, 200ms) var(--ease-standard, ease), border-color var(--t-base, 200ms) var(--ease-standard, ease);
  }
  .dpanel.glass.glass.is-useful {
    opacity: 1; visibility: visible; pointer-events: auto; transform: none;
    transition: opacity var(--t-base, 200ms) var(--ease-standard, ease), transform var(--t-base, 200ms) var(--ease-standard, ease),
      grid-template-rows var(--t-unfold, 460ms) var(--ease-unfold, ease), visibility 0s linear 0s,
      background-color var(--t-base, 200ms) var(--ease-standard, ease), box-shadow var(--t-base, 200ms) var(--ease-standard, ease), border-color var(--t-base, 200ms) var(--ease-standard, ease);
  }
  .dpanel:not(.is-open) { grid-template-rows: 0fr auto; }
  .dpanel-head {
    order: 2;
    appearance: none; background: transparent; border: 0; color: var(--ink); cursor: pointer;
    display: flex; align-items: center; gap: 8px; padding: 10px 12px 10px 14px; text-align: left;
    font-family: var(--font-sans); font-size: 13px; color: var(--ink-2);
  }
  .dpanel-head b { font-family: var(--font-mono); font-weight: 600; font-size: 15px; color: var(--ink); font-variant-numeric: tabular-nums; }
  .dpanel-head .dpanel-chev { margin-left: auto; color: var(--ink-3); display: inline-flex; transition: transform var(--t-slow, 280ms) var(--ease-standard, ease); }
  .dpanel.is-open .dpanel-head .dpanel-chev { transform: rotate(180deg); }   /* up when closed (the list grows upward), down when open */
  .dpanel-head:hover { color: var(--ink); }
  .dpanel-head:focus-visible { outline: 2px solid var(--accent); outline-offset: -2px; border-radius: 12px; }
  .dpanel-body { order: 1; min-height: 0; overflow-y: auto; overscroll-behavior: contain; padding: 8px 8px 0; border-bottom: 1px solid var(--rule-2); }
  .dpanel:not(.is-open) .dpanel-body { visibility: hidden; transition: visibility 0s linear var(--t-unfold, 460ms); }   /* hide after the collapse, not before */
  .dpanel.is-open .dpanel-body { transition: visibility 0s linear 0s; }
  /* The pull tab rides the drawer's edge; slide with it (hover-expand, 2026-09-21). */
  body .mob-toggle.mob-toggle.left { transition: left var(--t-unfold, 460ms) var(--ease-unfold, ease), transform var(--t-fast, 120ms) var(--ease-standard, ease), color var(--t-fast, 120ms), background-color var(--t-base, 200ms), box-shadow var(--t-base, 200ms), border-color var(--t-base, 200ms); }
  aside.left.glass.glass {
    transition: transform var(--t-unfold, 460ms) var(--ease-unfold, ease), visibility 0s linear var(--t-unfold, 460ms),
      background-color var(--t-base, 200ms) var(--ease-standard, ease), box-shadow var(--t-base, 200ms) var(--ease-standard, ease), border-color var(--t-base, 200ms) var(--ease-standard, ease);
  }
  aside.left.glass.glass.open {
    transition: transform var(--t-unfold, 460ms) var(--ease-unfold, ease), visibility 0s linear 0s,
      background-color var(--t-base, 200ms) var(--ease-standard, ease), box-shadow var(--t-base, 200ms) var(--ease-standard, ease), border-color var(--t-base, 200ms) var(--ease-standard, ease);
  }
  /* Tips lost their fade to the same override. */
  .tip.tip.glass { transition: opacity var(--t-fast, 120ms) var(--ease-standard, ease), transform var(--t-fast, 120ms) var(--ease-standard, ease), background-color var(--t-base, 200ms), box-shadow var(--t-base, 200ms), border-color var(--t-base, 200ms); }
  .dpanel .msheet-row {
    appearance: none; background: transparent; border: 0; border-bottom: 1px solid var(--rule-2);
    width: 100%; display: grid; grid-template-columns: 8px 1fr auto; gap: 10px; align-items: center;
    padding: 9px 6px; text-align: left; color: var(--ink); cursor: pointer; font-family: var(--font-sans);
  }
  .dpanel .msheet-row:last-child { border-bottom: 0; }
  .dpanel .msheet-row:hover { background: var(--surface-strong, var(--bg-2)); border-radius: 6px; }
  .dpanel .msheet-row .ldot { width: 8px; height: 8px; border-radius: 50%; }
  .dpanel .msheet-rname { font-size: 13px; font-weight: 500; line-height: 1.25; }
  .dpanel .msheet-rmeta { font-family: var(--font-mono); font-size: 10.5px; color: var(--ink-3); letter-spacing: .04em; white-space: nowrap; }
  .dpanel .msheet-empty { padding: 18px 8px; color: var(--ink-3); font-size: 13px; text-align: center; }
  body .region-nav.region-nav button {
    width: 44px; min-height: 32px; padding: 0;
    border-radius: var(--r-soft, 8px);
    background-color: var(--surface, var(--surface-overlay)); background-image: var(--surface-image, none);
    border: 1px solid var(--surface-edge, var(--rule)); box-shadow: var(--surface-shadow, none);
    backdrop-filter: var(--surface-blur, none); -webkit-backdrop-filter: var(--surface-blur, none);
    font-size: 10.5px; letter-spacing: 0.1em;
  }
  .msheet { display: none !important; }
}

/* Shell bars (2026-09-20): the Astro header and footer are fixed glass over
   the map; --shell-top / --shell-bottom are their overlap with this frame
   (map-mobile-sheet.js). Legacy chrome that anchors to the frame's edges
   moves in by the same amount. Top level, not inside a device block, and
   `html body` so it outranks the embed styles map-i18n.js injects at runtime. */
html body.embed-mode .kbd-hint { bottom: calc(14px + var(--shell-bottom, 0px)); }
html body.embed-mode aside.left, html body.embed-mode aside.right { top: var(--shell-top, 0px) !important; bottom: var(--shell-bottom, 0px) !important; }
@media (max-width: 900px) {
  html body.embed-mode aside.left, html body.embed-mode aside.right { height: auto !important; }
  html body.embed-mode .sheet { bottom: var(--shell-bottom, 0px); padding-bottom: max(0px, calc(env(safe-area-inset-bottom, 0px) - var(--shell-bottom, 0px))); }
  html body.embed-mode .tip.tip { bottom: calc(76px + var(--shell-bottom, 0px)) !important; }
}
@media (max-width: 480px) { html body.embed-mode .tip.tip { bottom: calc(64px + var(--shell-bottom, 0px)) !important; } }
/* Desktop detail card: beside the zoom column, not over it (the column is 36 px
   wide at right 16 px), and ending above the in-view panel's peek bar
   (39 px at bottom 16 px), so opening an entry hides no control. 2026-09-21. */
@media (min-width: 901px) { html body.embed-mode .sheet { top: calc(var(--shell-top, 0px) + 16px); right: 68px; max-height: calc(100vh - var(--shell-top, 0px) - var(--shell-bottom, 0px) - 16px - 71px); } }

/* ---------- phone / narrow: four controls + one sheet ------------------- */
@media (max-width: 900px) {
  :root { --msheet-h: 112px; }
  /* Everything the sheet absorbs */
  body .sdl-fab.sdl-fab, body .wm-reopen.wm-reopen, body #sdl-clear-floating,
  body .mob-toggle.mob-toggle, body .region-nav.region-nav, .drawer-backdrop, .dpanel { display: none !important; }
  /* The one remaining map button sits just above the sheet's peek edge */
  body .zoom-ctl.zoom-ctl {
    bottom: calc(var(--msheet-h) + 12px + var(--shell-bottom, 0px) + env(safe-area-inset-bottom, 0px)) !important;
    right: 12px !important;
    padding: 0 !important; border-radius: var(--r-soft, 8px) !important;
    box-shadow: var(--surface-shadow, none) !important;
    transition: bottom .28s cubic-bezier(.4, 0, .2, 1), background-color var(--t-base, 200ms), box-shadow var(--t-base, 200ms);
  }
  body .zoom-ctl.zoom-ctl { background: none !important; border: 0 !important; }
  body .zoom-ctl.zoom-ctl #z-reset {
    width: 44px !important; height: 44px !important; border-radius: var(--r-soft, 8px) !important;
    border: 1px solid var(--surface-edge, var(--rule)) !important;
    background-color: var(--surface, var(--surface-overlay)) !important; background-image: var(--surface-image, none) !important;
    -webkit-backdrop-filter: var(--surface-blur, none) !important; backdrop-filter: var(--surface-blur, none) !important;
    box-shadow: var(--surface-shadow, none) !important; color: var(--ink-2) !important;
  }
  body .zoom-ctl.zoom-ctl #z-reset svg { width: 20px; height: 20px; }
  body.msheet-open .zoom-ctl.zoom-ctl { opacity: 0; pointer-events: none; }

  .msheet {
    position: fixed; left: 0; right: 0; bottom: var(--shell-bottom, 0px);   /* above the shell's fixed footer */
    height: var(--msheet-h);
    z-index: 60;                          /* under the detail sheet (105) */
    display: grid; grid-template-rows: auto 1fr;
    background-color: var(--surface, var(--surface-deep));
    background-image: var(--surface-image, none);
    -webkit-backdrop-filter: var(--surface-blur, none); backdrop-filter: var(--surface-blur, none);
    border-top: 1px solid var(--surface-edge, var(--rule));
    border-radius: var(--r-loose, 14px) var(--r-loose, 14px) 0 0;
    box-shadow: var(--surface-shadow, 0 -6px 24px rgba(0, 0, 0, 0.28));
    padding-bottom: max(0px, calc(env(safe-area-inset-bottom, 0px) - var(--shell-bottom, 0px)));   /* the footer already clears the home indicator */
    transition: height .28s cubic-bezier(.4, 0, .2, 1), background-color var(--t-base, 200ms), box-shadow var(--t-base, 200ms);
    font-family: var(--font-sans);
    color: var(--ink);
    touch-action: pan-y;
  }
  .msheet.msheet.is-dragging { transition: none; }
  /* A grid row of 1fr still grows to its content unless the item may shrink;
     without min-height:0 the list ran below the viewport and nothing scrolled. */
  .msheet { overflow: hidden; }
  .msheet-body { min-height: 0; }
  .msheet-head { padding: 6px 14px 8px; touch-action: none; user-select: none; -webkit-user-select: none; }
  .msheet-bar { display: block; width: 40px; height: 4px; border-radius: 2px; background: var(--ink-3); opacity: .6; margin: 2px auto 8px; }
  .msheet-row1 { display: flex; align-items: center; gap: 8px; min-height: 40px; }
  .msheet-tab {
    appearance: none; background: transparent; border: 1px solid transparent; color: var(--ink-2);
    font: 500 14px/1 var(--font-sans); padding: 0 12px; min-height: 40px; border-radius: var(--r-soft, 8px);
    display: inline-flex; align-items: center; gap: 6px; cursor: pointer;
  }
  .msheet-tab b { font-family: var(--font-mono); font-weight: 600; font-size: 15px; color: var(--ink); font-variant-numeric: tabular-nums; }
  .msheet-tab .msheet-badge { font-family: var(--font-mono); font-size: 11px; padding: 1px 7px; border-radius: 10px; background: var(--accent); color: var(--bg); }
  .msheet-tab .msheet-badge[hidden] { display: none; }
  .msheet[data-state="peek"] .msheet-tab { border-color: transparent; }
  .msheet:not([data-state="peek"]) .msheet-tab.is-on { border-color: var(--rule); background: var(--bg-2); color: var(--ink); }
  .msheet-grip { margin-left: auto; width: 44px; height: 40px; appearance: none; background: transparent; border: 0; color: var(--ink-3); cursor: pointer; display: inline-flex; align-items: center; justify-content: center; border-radius: var(--r-soft, 8px); }
  .msheet-grip svg { transition: transform .28s; }
  .msheet:not([data-state="peek"]) .msheet-grip svg { transform: rotate(180deg); }
  .msheet-row2 { display: flex; gap: 5px; margin-top: 4px; align-items: center; }
  .msheet-chip {
    flex: 1 1 0; min-width: 0; min-height: 40px; padding: 0 2px; appearance: none; cursor: pointer;
    background: transparent; border: 1px solid var(--rule); color: var(--ink-2);
    border-radius: var(--r-soft, 8px);
    font: 600 9.5px/1 var(--font-mono); letter-spacing: .03em; text-transform: uppercase;
    white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
  }
  .msheet-chip.is-on { border-color: var(--accent); color: var(--accent); }
  .msheet-sep { width: 1px; height: 24px; background: var(--rule); margin: 0 2px; flex: 0 0 auto; }
  /* About · Data · Globe/flat: the three things that used to be floating buttons */
  .msheet-ico {
    flex: 0 0 40px; width: 40px; height: 40px; appearance: none; cursor: pointer;
    background: transparent; border: 1px solid var(--rule); color: var(--ink-2);
    border-radius: var(--r-soft, 8px); display: inline-flex; align-items: center; justify-content: center;
  }
  .msheet-ico:active { background: var(--bg-3); color: var(--ink); }
  .msheet .ico-flat { display: none; }
  .msheet.is-flat .ico-flat { display: inline; }
  .msheet.is-flat .ico-globe { display: none; }

  .msheet-body { overflow-y: auto; -webkit-overflow-scrolling: touch; overscroll-behavior: contain; touch-action: pan-y; padding: 0 14px 16px; }
  .msheet[data-state="peek"] .msheet-body { visibility: hidden; }
  .msheet-pane[hidden] { display: none; }
  .msheet-row {
    width: 100%; display: grid; grid-template-columns: 12px 1fr auto; align-items: center; gap: 12px;
    appearance: none; background: transparent; border: 0; border-bottom: 1px solid var(--rule-2);
    color: var(--ink); text-align: left; padding: 12px 2px; min-height: 52px; cursor: pointer;
  }
  .msheet-row .ldot { width: 10px; height: 10px; border-radius: 50%; }
  .msheet-rname { font-size: 15px; font-weight: 500; line-height: 1.25; }
  .msheet-rmeta { font-family: var(--font-mono); font-size: 11px; color: var(--ink-3); letter-spacing: .04em; white-space: nowrap; }
  .msheet-empty { padding: 26px 8px; text-align: center; color: var(--ink-3); font-size: 14px; }
  /* Filter groups moved in from the two desktop asides keep their own styles */
  #msheet-filters .section-h:first-child { margin-top: 12px; }
  .msheet-actions { display: grid; grid-template-columns: 1fr 1fr; gap: 8px; margin-top: 18px; padding-top: 14px; border-top: 1px solid var(--rule); }
  .msheet-action {
    min-height: 44px; appearance: none; cursor: pointer;
    background: var(--bg-2); border: 1px solid var(--rule); color: var(--ink);
    border-radius: var(--r-soft, 8px); font: 500 14px/1 var(--font-sans);
    display: inline-flex; align-items: center; justify-content: center; text-decoration: none;
  }
  .msheet-action:active { background: var(--bg-3); }
  @media (prefers-reduced-motion: reduce) {
    .msheet, body .zoom-ctl.zoom-ctl, .msheet-grip svg, .dpanel, .dpanel-body, aside.left, body .mob-toggle.mob-toggle.left { transition: none !important; }
  }
}

/* The keyboard hint and the zoom hint share the bottom centre; only one may show. */
body.marker-hovered .zoom-hint { opacity: 0 !important; }

/* ---------- motion (2026-09-20): answers an action, explains a change --------- */
/* Control response: press, hover lift (pointer devices), focus ring. */
.zoom-ctl button, .region-nav button, .msheet-ico, .msheet-chip, .msheet-action, .msheet-tab, .msheet-grip,
body .sdl-fab.sdl-fab, body .wm-reopen.wm-reopen, body #sdl-clear-floating {
  transition: transform var(--t-fast, 120ms) var(--ease-standard, ease), color var(--t-base, 200ms), border-color var(--t-base, 200ms), background-color var(--t-base, 200ms), opacity var(--t-slow, 280ms) var(--ease-enter, ease-out);
}
.zoom-ctl button:active, .region-nav button:active, .msheet-ico:active, .msheet-chip:active, .msheet-action:active, .msheet-tab:active,
body .sdl-fab.sdl-fab:active, body .wm-reopen.wm-reopen:active, body #sdl-clear-floating:active { transform: scale(0.96) !important; }
@media (hover: hover) {
  .region-nav button:hover, body .sdl-fab.sdl-fab:hover, body .wm-reopen.wm-reopen:hover, body #sdl-clear-floating:hover { transform: translateY(-1px) !important; }
}
.zoom-ctl button:focus-visible, .region-nav button:focus-visible, .msheet-ico:focus-visible, .msheet-chip:focus-visible, .msheet-action:focus-visible, .msheet-tab:focus-visible, .msheet-grip:focus-visible,
body .sdl-fab.sdl-fab:focus-visible, body .wm-reopen.wm-reopen:focus-visible { outline: 2px solid var(--ink); outline-offset: 2px; }
/* Arrival: chrome holds back until the map has assembled (body.arriving is
   set by the map for 900 ms, once per session). Triple class out-specifies
   the runtime !important rules. */
body.arriving .glass.glass.glass, body.arriving .region-nav.region-nav { opacity: 0 !important; pointer-events: none; }
.msheet.msheet { transition: height .28s var(--ease-standard, cubic-bezier(.4, 0, .2, 1)), background-color var(--t-base, 200ms), box-shadow var(--t-base, 200ms), opacity var(--t-slow, 280ms) var(--ease-enter, ease-out), transform var(--t-slow, 280ms) var(--ease-enter, ease-out); }
.msheet.msheet.is-springing, .msheet.msheet.is-dragging { transition: background-color var(--t-base, 200ms), box-shadow var(--t-base, 200ms); }
body.msheet-springing .zoom-ctl.zoom-ctl { transition: none !important; }
/* Tips arrive where you point: fade + 4 px rise. */
.tip.tip { transition: opacity var(--t-fast, 120ms) var(--ease-standard, ease), transform var(--t-fast, 120ms) var(--ease-standard, ease); transform: translateY(4px); }
.tip.tip.show { transform: none; }
/* Phone detail sheet: rows follow the sheet in, 30 ms apart. */
@keyframes sdl-row-in { from { opacity: 0; transform: translateY(6px); } to { opacity: 1; transform: none; } }
@media (max-width: 900px) {
  .sheet.open .sheet-row { animation: sdl-row-in var(--t-slow, 280ms) var(--ease-enter, ease-out) both; animation-delay: calc(var(--i, 0) * 30ms); }
}
@media (prefers-reduced-motion: reduce) {
  .zoom-ctl button, .region-nav button, .msheet-ico, .msheet-chip, .msheet-action, .msheet-tab, .msheet-grip, .msheet.msheet, .tip.tip, .sheet, .sheet-row,
  body .sdl-fab.sdl-fab, body .wm-reopen.wm-reopen, body #sdl-clear-floating { transition: none !important; animation: none !important; }
  body.arriving .glass.glass.glass, body.arriving .region-nav.region-nav { opacity: 1 !important; pointer-events: auto; }
}

/* Arrival rings: one sonar ping as each pin or disc lands (once per session). */
.arrive-ring, .c-ripple { fill: none; stroke: currentColor; stroke-width: 1.5px; opacity: 0; pointer-events: none; transform-box: fill-box; transform-origin: center; vector-effect: non-scaling-stroke; }
.c-ripple { stroke: var(--ink-3); }
.marker.arrive .arrive-ring, .cluster.arrive .c-ripple { animation: sdl-arrive-ring 720ms var(--ease-exit, ease-out) 1 both; }
@keyframes sdl-arrive-ring { 0% { transform: scale(1); opacity: .6; } 100% { transform: scale(2.8); opacity: 0; } }
body.arriving .msheet.msheet.msheet { transform: translateY(28px); }
@media (prefers-reduced-motion: reduce) { .arrive-ring, .c-ripple { animation: none !important; } body.arriving .msheet.msheet.msheet { transform: none; } }

/* ---- Story mode + idle cinematic (map-story.js, 2026-09-21) ------------------
   Play sits with the top-left controls on desktop and top-left on phones; for a
   visitor who has never played it is a labelled pill. The caption is a strong
   glass card; the progress pill carries year and count. While the story runs
   the rest of the chrome fades to a whisper and stops taking input. */
body #sdl-story-play.sdl-fab { display: inline-flex; align-items: center; justify-content: center; gap: 8px; }
body #sdl-story-play .story-lbl { display: none; font-family: var(--font-sans); font-size: 13px; font-weight: 500; color: var(--ink); white-space: nowrap; }
body #sdl-story-play.is-pill { width: auto !important; padding: 0 14px 0 10px !important; }
body #sdl-story-play.is-pill .story-lbl { display: inline; }
body #sdl-story-play .story-ico-stop { display: none; }
body #sdl-story-play.is-on .story-ico-play { display: none; }
body #sdl-story-play.is-on .story-ico-stop { display: inline; }
body #sdl-story-play.is-on { color: var(--ink) !important; border-color: var(--ink-3) !important; }
@media (min-width: 901px) {
  body.embed-mode #sdl-story-play.sdl-fab { position: fixed; top: calc(16px + var(--shell-top, 0px)) !important; left: 192px !important; z-index: 70; }
  body:not(.embed-mode) #sdl-story-play.sdl-fab { position: fixed; top: calc(var(--header-h, 92px) + 16px); left: 192px; z-index: 70; }
}
@media (max-width: 900px) {
  /* Phones hide the old floating buttons (.sdl-fab) in favour of the sheet; Play is the exception. */
  body #sdl-story-play.sdl-fab { display: inline-flex !important; position: fixed; top: calc(12px + var(--shell-top, 0px)); left: 12px; z-index: 70; width: 40px; height: 40px; border-radius: var(--r-soft, 8px); }
  body #sdl-story-play.is-pill { height: 40px; }
}
.story-cap {
  position: fixed; left: 50%; transform: translate(-50%, 10px); z-index: 80;
  bottom: calc(76px + var(--shell-bottom, 0px));
  width: min(560px, calc(100vw - 32px)); padding: 16px 20px 18px;
  border: 1px solid var(--surface-edge, var(--rule)); border-radius: 12px;
  color: var(--ink); font-family: var(--font-sans); text-align: left;
  opacity: 0; visibility: hidden; pointer-events: none;
}
.story-cap.glass.glass { transition: opacity var(--t-slow, 280ms) var(--ease-standard, ease), transform var(--t-slow, 280ms) var(--ease-standard, ease), visibility 0s linear var(--t-slow, 280ms), background-color var(--t-base, 200ms), box-shadow var(--t-base, 200ms), border-color var(--t-base, 200ms); }
.story-cap.glass.glass.show { opacity: 1; visibility: visible; transform: translate(-50%, 0); transition: opacity var(--t-slow, 280ms) var(--ease-standard, ease), transform var(--t-slow, 280ms) var(--ease-standard, ease), visibility 0s linear 0s, background-color var(--t-base, 200ms), box-shadow var(--t-base, 200ms), border-color var(--t-base, 200ms); }
.story-year { font-family: var(--font-mono); font-size: 28px; font-weight: 600; letter-spacing: .02em; color: var(--accent); line-height: 1; margin-bottom: 8px; font-variant-numeric: tabular-nums; }
.story-title { font-size: 15px; font-weight: 600; margin-bottom: 4px; }
.story-line { font-size: 14px; line-height: 1.45; color: var(--ink-2); }
.story-src { margin-top: 8px; font-family: var(--font-mono); font-size: 10.5px; letter-spacing: .04em; color: var(--ink-3); word-break: break-all; }
.story-src:empty { display: none; }
.story-prog {
  position: fixed; left: 50%; transform: translateX(-50%); z-index: 80;
  bottom: calc(24px + var(--shell-bottom, 0px));
  padding: 6px 12px; border: 1px solid var(--surface-edge, var(--rule)); border-radius: 999px;
  font-family: var(--font-mono); font-size: 11.5px; letter-spacing: .08em; color: var(--ink-2);
  white-space: nowrap; pointer-events: none; opacity: 0; transition: opacity var(--t-base, 200ms);
}
.story-prog:not(:empty) { opacity: 1; }
body.story-on .story-prog:not(:empty) { opacity: 1; }
@media (max-width: 900px) {
  .story-cap { bottom: calc(var(--shell-bottom, 0px) + 64px); padding: 14px 16px 16px; }
  .story-year { font-size: 24px; }
  .story-prog { bottom: calc(var(--shell-bottom, 0px) + 18px); }
}
/* The rest of the chrome steps back while the story runs (and during the idle
   spin). Names on the map stay. */
body.story-on .zoom-ctl, body.story-on .region-nav, body.story-on .dpanel, body.story-on .mob-toggle, body.story-on .kbd-hint, body.story-on .msheet,
body.story-on .sdl-fab:not(.story-ctl), body.story-on .wm-reopen, body.story-on #sdl-clear-floating, body.story-on #reset {
  opacity: 0.12 !important; pointer-events: none !important; transition: opacity 400ms var(--ease-standard, ease) !important;
}
body.story-on .tip, body.story-on .kbd-hint { display: none !important; }
@media (prefers-reduced-motion: reduce) { .story-cap.glass.glass, .story-prog { transition: none !important; } }
