/* Sudan Rail Group: motion diagrams.
 *
 * Loaded only while MOTION is on in build.py, next to site.css, which it
 * never changes. Five diagrams build once, as the reader reaches them: the
 * corridor map, the concession, the programme, the capacity chart and the
 * history map. While this file is loaded it widens the rule at the foot of
 * site.css, which lets only the corridor line move.
 *
 * Rules for everything in here:
 *   - Each element's own style is its end frame. The hidden and moving
 *     states exist only on a screen, under html.motion, with no request for
 *     reduced motion. Print, reduced motion and a page without JavaScript
 *     all get the finished diagram.
 *   - A diagram (data-motion) starts when motion.js adds .play, and plays
 *     once. Nothing loops. motion.js adds .done once it has finished (or
 *     before printing), which takes the animations off, so a resize or a
 *     change of setting shows the end frame rather than playing it again.
 *   - Figures count only to published values, and a stage with no figure
 *     never grows.
 */

/* a figure's copy for screen readers, which never hear it count */
.mo-sr { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap; }

/* ══ maps (the corridor and the history) ═════════════════════ */
.mo-map { position: relative; }
.mo-map svg { display: block; width: 100%; height: auto; overflow: hidden; }
.mo-coast, .mo-river, .mo-ghost, .mo-line { fill: none; }
.mo-river { stroke-width: 2.2; stroke-linecap: round; }
.mo-coast { stroke-width: 1.2; }
.mo-line { stroke-linejoin: round; stroke-linecap: round; stroke-dasharray: 1 1; stroke-dashoffset: 0; }
.mo-stop { transform-box: fill-box; transform-origin: center; }

.mo-geo, .mo-tag, .mo-lbl { position: absolute; white-space: nowrap; pointer-events: none; }
.mo-geo { font: 500 11px var(--font-sans); letter-spacing: .08em; text-transform: uppercase; transform: translate(-50%, -50%); }
.mo-geo.is-start { transform: translate(0, -50%); }
[lang="ar"] .mo-geo { font-size: 12px; }
.mo-tag { font: 500 12.5px var(--font-mono); transform: translate(-50%, -50%); padding: 0 4px; }
.mo-lbl { line-height: 1.25; }
.mo-lbl b { display: block; font: 600 14px/1.3 var(--font-sans); }
.mo-lbl small { display: block; font-size: 12px; }
.mo-lbl.is-e { transform: translate(14px, -50%); text-align: left; }
.mo-lbl.is-w { transform: translate(calc(-100% - 14px), -50%); text-align: right; }
.mo-lbl.is-se { transform: translate(10px, 7px); text-align: left; }
.mo-lbl.is-sw { transform: translate(calc(-100% - 10px), 7px); text-align: right; }
.mo-lbl.is-ne { transform: translate(8px, calc(-100% - 8px)); text-align: left; }
.mo-lbl.is-nw { transform: translate(calc(-100% - 8px), calc(-100% - 8px)); text-align: right; }

/* 01 · the corridor, on navy */
.mo-corridor { display: grid; grid-template-columns: minmax(0, .8fr) minmax(0, 1.2fr); gap: 3rem; align-items: center; margin-top: 1rem; }
.srg p.mo-total { margin: 0; font: 500 clamp(3.4rem, 2rem + 5vw, 5.6rem)/1 var(--font-mono); color: var(--on-pane); font-variant-numeric: tabular-nums; letter-spacing: -.03em; }
.srg p.mo-total__l { margin: .7rem 0 0; color: var(--on-pane-lede); font-size: 1.02rem; }
.srg .mo-corridor .srg-map-legend { border-top: 1px solid var(--line-on-pane); padding-top: 1rem; margin-top: 1.8rem; color: var(--on-pane-meta); font-size: .92rem; }
.mo-corridor__copy > .srg-kicker { margin-bottom: 1.4rem; }
.mo-map.is-corridor .mo-sea { fill: #0f2d4a; }
.mo-map.is-corridor .mo-coast { stroke: rgba(255, 255, 255, .2); }
.mo-map.is-corridor .mo-river { stroke: #3d78a8; opacity: .8; }
.mo-map.is-corridor .mo-ghost { stroke: rgba(255, 255, 255, .28); stroke-width: 2; stroke-dasharray: 2 6; }
.mo-map.is-corridor .mo-line { stroke: var(--accent-on-dark); stroke-width: 4; }
.mo-map.is-corridor .mo-stop { fill: var(--pane); stroke: var(--accent-on-dark); stroke-width: 2.5; }
.mo-map.is-corridor .mo-stop.is-end { fill: var(--accent-on-dark); stroke: var(--pane); stroke-width: 3; }
.mo-map.is-corridor .mo-lbl b { color: var(--on-pane); }
.mo-map.is-corridor .mo-lbl small { color: var(--on-pane-lede); }
.mo-map.is-corridor .mo-geo { color: var(--on-pane-meta); }

/* Home: the corridor band straight under the hero */
.mo-band { border-top: 1px solid var(--line-on-pane); }
.mo-band .mo-corridor { margin-top: 0; }

/* 06 · the history, on paper */
.mo-history { display: grid; grid-template-columns: minmax(0, .72fr) minmax(0, 1.28fr); gap: 3rem; align-items: center; margin-top: 1rem; }
.mo-steps { list-style: none; margin: 0; padding: 0; border-top: 1px solid var(--line); }
.mo-steps li { padding: 1rem 0; border-bottom: 1px solid var(--line); }
.mo-steps__y { display: block; font: 500 15px var(--font-mono); color: var(--accent-text); margin-bottom: .25rem; }
.srg .mo-steps p { margin: 0; color: var(--ink); }
.srg .mo-history .srg-map-legend { margin-top: 1rem; font-size: .9rem; }
.mo-map.is-history { background: #fff; border: 1px solid var(--line); }
.mo-map.is-history .mo-sea { fill: #eaf1f7; }
.mo-map.is-history .mo-coast { stroke: #b3c4d4; }
.mo-map.is-history .mo-river { stroke: #86add0; }
.mo-map.is-history .mo-line { stroke: var(--pane); stroke-width: 3.5; }
.mo-map.is-history .mo-stop { fill: var(--pane); stroke: #fff; stroke-width: 2.5; }
.mo-map.is-history .mo-lbl b { color: var(--ink); }
.mo-map.is-history .mo-lbl small { color: var(--muted); }
.mo-map.is-history .mo-geo { color: var(--muted); }
.mo-map.is-history .mo-tag { color: var(--accent-text); background: #fff; }

/* ══ 03 · the concession ═════════════════════════════════════ */
.mo-deal { position: relative; margin-top: 2.2rem; }
.mo-deal__rail { position: relative; height: 44px; }
.mo-deal__line { position: absolute; top: 20px; height: 3px; inset-inline: 22px; background: var(--accent); transform-origin: right center; }
[dir="rtl"] .mo-deal__line { transform-origin: left center; }
.mo-deal__node { position: absolute; top: 11px; width: 22px; height: 22px; }
.mo-deal__node.is-assets { inset-inline-start: 0; background: var(--pane); outline: 2px solid transparent; }
.mo-deal__node.is-srg { inset-inline-end: 0; background: var(--accent); }
.mo-deal__arrow { position: absolute; top: 15.5px; inset-inline-start: 24px; width: 0; height: 0; border-block: 6px solid transparent; border-inline-end: 11px solid var(--accent); }
.mo-deal__flow { position: absolute; bottom: 30px; left: 50%; transform: translateX(-50%); font: 500 13px var(--font-sans); color: var(--accent-text); white-space: nowrap; }
.mo-deal__via { display: none; }
.mo-deal__pkt { position: absolute; top: 16.5px; width: 10px; height: 10px; background: var(--accent); inset-inline-start: 26px; opacity: 0; display: none; }
.mo-deal__cols { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1.25fr) minmax(0, 1fr); gap: 2.25rem; margin-top: 1.1rem; }
.mo-deal__col h3 { font: var(--srg-cols-title); color: var(--ink); margin: 0 0 .45rem; }
.srg .mo-deal__col p { margin: 0; font-size: .96rem; color: var(--muted); }
.mo-deal__col.is-srg { text-align: end; }
.mo-deal__col.is-deal { text-align: center; }
.mo-deal__bracket { height: 12px; border: 1px solid var(--muted); border-top: 0; margin: -6px 0 14px; }
.srg .mo-deal .mo-zero { margin: 1.4rem 0 0; display: flex; align-items: baseline; gap: .8rem; }
.mo-zero b { font: 500 46px/1 var(--font-mono); color: var(--ink); border-bottom: 3px solid var(--accent); padding-bottom: 2px; }
.mo-zero > span { font-size: .95rem; color: var(--ink); font-weight: 500; }

/* ══ 04 · the programme ══════════════════════════════════════ */
.mo-track__list { list-style: none; margin: 0; padding: 70px 0 0; display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); }
.mo-track__stage { position: relative; padding-top: 38px; padding-inline-end: 1.75rem; }
.mo-track__seg { position: absolute; top: 6px; inset-inline: 0; height: 3px; background: repeating-linear-gradient(90deg, #b7c3cf 0 8px, transparent 8px 14px); transform-origin: left center; }
[dir="rtl"] .mo-track__seg { transform-origin: right center; }
.mo-track__stage.is-past .mo-track__seg { background: var(--pane); }
.mo-track__stage.is-now .mo-track__seg { background: var(--accent); }
.mo-track__stage:last-child .mo-track__seg { -webkit-mask-image: linear-gradient(90deg, #000 45%, transparent); mask-image: linear-gradient(90deg, #000 45%, transparent); }
[dir="rtl"] .mo-track__stage:last-child .mo-track__seg { -webkit-mask-image: linear-gradient(270deg, #000 45%, transparent); mask-image: linear-gradient(270deg, #000 45%, transparent); }
.mo-track__node { position: absolute; top: 1px; inset-inline-start: 0; width: 13px; height: 13px; background: #fff; border: 2px solid #9fb0c0; }
.mo-track__stage.is-past .mo-track__node { background: var(--pane); border-color: var(--pane); }
.mo-track__stage.is-now .mo-track__node { background: var(--accent); border-color: var(--accent); }
.mo-track__ring { position: absolute; top: 1px; inset-inline-start: 0; width: 13px; height: 13px; border: 2px solid var(--accent); opacity: 0; }
.mo-track__here { position: absolute; top: -58px; inset-inline-start: -2px; font: 500 13px var(--font-mono); color: var(--accent-text); white-space: nowrap; padding-bottom: 30px; }
.mo-track__here::after { content: ""; position: absolute; bottom: 4px; inset-inline-start: 7px; width: 1px; height: 22px; background: var(--accent); }
.srg .mo-track__y { margin: 0 0 .3rem; font: 400 1rem var(--font-mono); color: var(--muted); }
.mo-track__stage.is-now .mo-track__y { color: var(--ink); font-weight: 600; }
.mo-track__stage h3 { font: var(--srg-cols-title); color: var(--ink); margin: 0 0 .4rem; }
.srg .mo-track__stage p:last-child { margin: 0; font-size: .94rem; color: var(--muted); }

/* ══ 05 · capacity ═══════════════════════════════════════════ */
.mo-chart { max-width: 860px; }
.mo-chart__plot { position: relative; height: 270px; display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 0 4%; border-bottom: 1px solid var(--ink); margin-top: 66px; }
.mo-chart__col { position: relative; height: 100%; }
.mo-bar { position: absolute; bottom: 0; left: 16%; right: 16%; height: var(--h); transform-origin: center bottom; }
.mo-bar.is-peak { background: var(--pane); }
.mo-bar.is-now { background: var(--accent); }
.mo-bar.is-pending { background: var(--chart-pending); outline: 1px dashed #aab7c4; outline-offset: -1px; }
.mo-bar__v { position: absolute; bottom: calc(var(--h) + 8px); left: 0; right: 0; text-align: center; font: 500 26px/1.2 var(--font-mono); color: var(--ink); font-variant-numeric: tabular-nums; }
.mo-bar__p { position: absolute; bottom: calc(var(--h) + 8px); left: 0; right: 0; text-align: center; font-size: 15px; color: var(--chart-pending-label); }
.mo-chart__peak { position: absolute; top: 0; left: 0; right: 0; border-top: 1.5px dashed var(--ink); z-index: 1; transform-origin: left center; }
[dir="rtl"] .mo-chart__peak { transform-origin: right center; }
.mo-chart__peak-l { position: absolute; top: -24px; inset-inline-end: 0; font-size: 13px; color: var(--ink); font-weight: 500; }
.mo-gap { position: absolute; top: 0; bottom: var(--h); inset-inline-start: 7%; width: 0; border-inline-start: 1.5px solid var(--accent-text); transform-origin: center bottom; }
.mo-gap::before, .mo-gap::after { content: ""; position: absolute; inset-inline-start: -7px; width: 12px; height: 0; border-top: 1.5px solid var(--accent-text); }
.mo-gap::before { top: 0; }
.mo-gap::after { bottom: 0; }
.mo-gap__l { position: absolute; top: 14%; inset-inline-start: 16%; inset-inline-end: 0; font-size: 13px; line-height: 1.35; color: var(--accent-text); font-weight: 500; }
.mo-gap__l .is-short { display: none; }
.mo-chart__labels { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 0 4%; margin-top: 12px; text-align: center; }
.mo-chart__labels b { display: block; color: var(--ink); font-weight: 600; font-size: 15px; line-height: 1.3; }
.mo-chart__labels b.is-q { font-weight: 400; color: var(--muted); }
.mo-chart__labels small { display: block; color: var(--muted); font-size: 13.5px; }

/* ══ narrower screens ════════════════════════════════════════ */
@media (max-width: 1000px) {
  .mo-corridor, .mo-history { grid-template-columns: 1fr; gap: 2rem; }
  /* stacked, the history map comes first, so it is on screen when it plays */
  .mo-history__copy { order: 1; }
}
@media (max-width: 760px) {
  /* 03: the agreement runs down the page, the public assets at the top */
  .mo-deal { padding-inline-start: 50px; margin-top: 1.6rem; }
  .mo-deal__rail { position: absolute; inset-block: 0; inset-inline-start: 0; width: 22px; height: auto; }
  .mo-deal__line { top: 22px; bottom: 22px; inset-inline: 9.5px auto; width: 3px; height: auto; transform-origin: center bottom; }
  [dir="rtl"] .mo-deal__line { transform-origin: center bottom; }
  .mo-deal__node.is-assets { top: 0; }
  .mo-deal__node.is-srg { top: auto; bottom: 0; inset-inline: 0 auto; }
  .mo-deal__arrow { top: 24px; inset-inline-start: 5px; border-block: 0 solid transparent; border-inline: 6px solid transparent; border-block-end: 11px solid var(--accent); }
  /* the label leaves the rail for the agreement column (see sec_flow) */
  .mo-deal__flow { display: none; }
  .srg p.mo-deal__via { display: block; margin: 0 0 .35rem; font: 500 13px var(--font-sans); color: var(--accent-text); }
  .mo-deal__pkt { inset-inline-start: 6px; top: 26px; }
  .mo-deal__cols { grid-template-columns: 1fr; gap: 1.9rem; margin-top: 0; }
  .mo-deal__col.is-srg, .mo-deal__col.is-deal { text-align: start; }
  .mo-deal__bracket { display: none; }
  /* 04: the track runs down the page */
  .mo-track__list { grid-template-columns: 1fr; padding-top: 50px; }
  .mo-track__stage { padding: 0 0 30px; padding-inline-start: 36px; }
  .mo-track__seg { top: 8px; bottom: 0; inset-inline: 5px auto; width: 3px; height: auto; background: repeating-linear-gradient(180deg, #b7c3cf 0 8px, transparent 8px 14px); transform-origin: center top; }
  [dir="rtl"] .mo-track__seg { transform-origin: center top; }
  .mo-track__stage:last-child .mo-track__seg, [dir="rtl"] .mo-track__stage:last-child .mo-track__seg { -webkit-mask-image: linear-gradient(180deg, #000 30%, transparent); mask-image: linear-gradient(180deg, #000 30%, transparent); }
  .mo-track__here { top: -44px; padding-bottom: 20px; }
  .mo-track__here::after { height: 14px; }
  /* 05: the gap label shortens */
  .mo-gap__l .is-full { display: none; }
  .mo-gap__l .is-short { display: inline; }
}
@media (max-width: 620px) {
  .mo-lbl b { font-size: 12.5px; }
  .mo-lbl small { font-size: 11px; }
  .mo-lbl:not(.is-end) small { display: none; }
  .mo-geo { font-size: 10px; }
  .mo-tag { font-size: 11px; }
  .mo-zero b { font-size: 40px; }
  .mo-chart__plot { height: 220px; }
  .mo-bar__v { font-size: 20px; }
  .mo-bar__p { font-size: 13px; }
  .mo-chart__labels b { font-size: 13px; }
  .mo-chart__labels small { font-size: 12px; }
}

/* ══ motion ══════════════════════════════════════════════════
   Only on a screen, only when the reader has not asked for reduced
   motion, and only once the head script has set html.motion. */
@media screen and (prefers-reduced-motion: no-preference) {
  .motion [data-motion]:not(.play) .mo-in, .motion [data-motion]:not(.play) .mo-rise,
  .motion [data-motion]:not(.play) .mo-pop, .motion [data-motion]:not(.play) .mo-vrise { opacity: 0; }
  .motion [data-motion]:not(.play) .mo-draw { stroke-dashoffset: 1; }
  .motion [data-motion]:not(.play) .mo-grow { transform: scaleX(0); }
  .motion [data-motion]:not(.play) .mo-grow-y { transform: scaleY(0); }
  .motion [data-motion]:not(.play) .mo-vrise { bottom: 8px; }

  .motion .play:not(.done) .mo-in { animation: mo-fade var(--d, .45s) ease var(--t, 0s) both; }
  .motion .play:not(.done) .mo-rise { animation: mo-rise var(--d, .5s) cubic-bezier(.2, .6, .2, 1) var(--t, 0s) both; }
  .motion .play:not(.done) .mo-pop { animation: mo-pop var(--d, .35s) cubic-bezier(.2, .6, .2, 1) var(--t, 0s) both; }
  .motion .play:not(.done) .mo-draw { animation: mo-draw var(--d, 1s) linear var(--t, 0s) both; }
  .motion .play:not(.done) .mo-grow { animation: mo-grow-x var(--d, .6s) cubic-bezier(.4, 0, .2, 1) var(--t, 0s) both; }
  .motion .play:not(.done) .mo-grow-y { animation: mo-grow-y var(--d, .8s) cubic-bezier(.2, .6, .2, 1) var(--t, 0s) both; }
  .motion .play:not(.done) .mo-vrise { animation: mo-vrise var(--d, .8s) cubic-bezier(.2, .6, .2, 1) var(--t, 0s) both; }

  /* maps: corridor stops light up as the line passes; history stops pop in,
     and each history line draws in amber, then settles to navy */
  .motion [data-motion]:not(.play) .is-corridor .mo-stop { stroke: rgba(255, 255, 255, .35); fill: var(--pane); }
  .motion .play:not(.done) .is-corridor .mo-stop { animation: mo-light .3s ease var(--t, 0s) both; }
  .motion [data-motion]:not(.play) .is-history .mo-stop { opacity: 0; }
  .motion .play:not(.done) .is-history .mo-stop { animation: mo-pop .35s cubic-bezier(.2, .6, .2, 1) calc(var(--t, 0s) - .05s) both; }
  .motion .play:not(.done) .is-history .mo-line { animation: mo-draw var(--d) linear var(--t) both, mo-settle .5s ease calc(var(--t) + var(--d)) both; }

  /* concession: the agreement draws out from Sudan Rail Group, investment
     travels to the public assets, and the line takes the accent */
  .motion .mo-deal__pkt { display: block; }
  .motion [data-motion]:not(.play) .mo-deal__line { transform: scaleX(0); }
  .motion .play:not(.done) .mo-deal__line { animation: mo-grow-x .7s cubic-bezier(.4, 0, .2, 1) .2s both, mo-tint .4s ease 2.35s both; }
  .motion .play:not(.done) .mo-deal__pkt { animation: mo-travel .9s cubic-bezier(.45, 0, .3, 1) var(--t) both; }
  .motion .play:not(.done) .mo-deal__node.is-assets { animation: mo-ring .7s ease-out 2.2s forwards; }

  /* programme: the segments run at one speed, the current stage pulses once */
  .motion .play:not(.done) .mo-track__seg { animation-timing-function: linear; }
  .motion .play:not(.done) .mo-track__ring { animation: mo-pulse .9s ease-out 1.15s both; }

  @media (max-width: 760px) {
    .motion [data-motion]:not(.play) .mo-deal__line { transform: scaleY(0); }
    .motion .play:not(.done) .mo-deal__line { animation-name: mo-grow-y, mo-tint; }
    .motion .play:not(.done) .mo-deal__pkt { animation-name: mo-travel-y; }
    .motion [data-motion]:not(.play) .mo-track__seg { transform: scaleY(0); }
    .motion .play:not(.done) .mo-track__seg { animation-name: mo-grow-y; }
  }
}

@keyframes mo-fade { from { opacity: 0; } }
@keyframes mo-rise { from { opacity: 0; transform: translateY(10px); } }
@keyframes mo-pop { from { opacity: 0; transform: scale(.2); } }
@keyframes mo-draw { from { stroke-dashoffset: 1; } }
@keyframes mo-grow-x { from { transform: scaleX(0); } }
@keyframes mo-grow-y { from { transform: scaleY(0); } }
@keyframes mo-vrise { from { bottom: 8px; opacity: 0; } 15% { opacity: 1; } }
@keyframes mo-light { from { stroke: rgba(255, 255, 255, .35); fill: #0b2239; } }
@keyframes mo-settle { from { stroke: #c9922b; } }
@keyframes mo-tint { from { background: #0d1b28; } }
@keyframes mo-travel { 0% { inset-inline-start: calc(100% - 32px); opacity: 0; } 12% { opacity: 1; } 88% { opacity: 1; } 100% { inset-inline-start: 26px; opacity: 0; } }
@keyframes mo-travel-y { 0% { top: calc(100% - 32px); opacity: 0; } 12% { opacity: 1; } 88% { opacity: 1; } 100% { top: 26px; opacity: 0; } }
@keyframes mo-ring { from { outline-color: rgba(201, 146, 43, 1); outline-offset: 0; } to { outline-color: rgba(201, 146, 43, 0); outline-offset: 14px; } }
@keyframes mo-pulse { from { opacity: .9; transform: scale(1); } to { opacity: 0; transform: scale(3.4); } }
