/* ===== 06 · Cities — Nigeria map (ported from Landing B "Coverage") =====
   Every selector is scoped under .cities. Colours are literal so the part
   also works without the host's tokens. The map sits out of its card,
   blended into the page (these used to live in site5/site.css). */

.cities{
  --ct-ink:#0A0A0A; --ct-muted:#525252; --ct-brand:#E55020; --ct-dark:#221F1C;
  --ct-slab:#2A211A; --ct-paper:#FBF6EC; --ct-white:#FFFFFF; --ct-peach:#FCE4D6;
  --ct-ease:cubic-bezier(.16,1,.3,1);
  --ct-pop:cubic-bezier(.34,1.56,.64,1);
  position:relative;
  background:var(--ct-paper);
  border-top:1.75px solid var(--ct-slab);
  border-bottom:1.75px solid var(--ct-slab);
  padding:var(--pad,48px) 0;
  overflow:hidden;
  color:var(--ct-ink);
  font-family:Manrope,system-ui,sans-serif;
}
.cities *, .cities *::before, .cities *::after{box-sizing:border-box}
.cities p, .cities h2, .cities ul{margin:0;padding:0}

/* Ben-Day dotted paper ground */
.cities .ct-dots{
  position:absolute;inset:0;pointer-events:none;
  background-image:radial-gradient(circle,rgba(10,10,10,.11) 1.6px,transparent 2px);
  background-size:26px 26px;
}

.cities .ct-grid{
  position:relative;
  width:100%;max-width:1248px;margin:0 auto;
  padding:0 16px;
  display:grid;
  grid-template-columns:minmax(0,1fr) minmax(0,1.1fr);
  column-gap:clamp(32px,5vw,64px);row-gap:24px;
  align-items:center;
}

@media (min-width:1281px){.cities .ct-grid{padding:0}}

/* ---------- left column ---------- */
.cities .ct-copy{max-width:540px}
.cities .ct-kicker{
  display:flex;align-items:center;gap:10px;
  font:800 12px/1 Manrope,system-ui,sans-serif;
  letter-spacing:.16em;text-transform:uppercase;color:var(--ct-brand);
}
.cities .ct-kicker span{
  display:inline-grid;place-items:center;height:24px;padding:0 8px;
  border-radius:8px;background:var(--ct-dark);color:#FAFAF8;letter-spacing:.06em;
}
.cities .ct-head{
  margin-top:0;
  font-family:Supreme,Manrope,sans-serif;font-weight:800;
  font-size:clamp(44px,min(5.6vw,9.4vh),84px);line-height:.96;letter-spacing:-.035em;
  color:var(--ct-ink);
}
.cities .ct-head em{font-style:normal;color:var(--ct-brand)}
.cities .ct-sub{
  margin-top:24px;max-width:440px;
  font-size:18px;line-height:1.55;font-weight:500;color:var(--ct-muted);
}

/* the four facts: one inline row under copy + map, split by rules, no cards */
.cities .ct-facts{
  grid-column:1 / -1;list-style:none;
  display:grid;grid-template-columns:repeat(4,minmax(0,1fr));
  border-top:2.5px solid var(--ct-slab);
}
.cities .ct-tile{
  display:grid;grid-template-columns:auto minmax(0,1fr);align-items:center;align-content:start;
  column-gap:8px;row-gap:4px;padding:16px 16px 0 0;
}
.cities .ct-tile + .ct-tile{padding-left:16px;border-left:1px solid rgba(42,33,26,.25)}
.cities .ct-tile b{font:800 18px/1.15 Supreme,Manrope,sans-serif;letter-spacing:-.01em;color:var(--ct-ink)}
.cities .ct-tile-line{grid-column:1 / -1;font:500 15px/1.45 Manrope,system-ui,sans-serif;color:var(--ct-muted)}
.cities .ct-tile-ico{display:inline-grid;place-items:center;flex:none;width:28px;height:28px;border-radius:8px;background:var(--ct-brand);color:#FFF8F4;border:1.5px solid var(--ct-slab)}
.cities .ct-tile-ico svg{display:block}
.cities .ct-tile-ico rect[stroke]{stroke:var(--ct-slab)}

/* ---------- right column: the map, out of its card ---------- */
.cities .ct-card{
  position:relative;
  background:transparent;border:0;border-radius:0;box-shadow:none;
  overflow:visible;
}
/* crop window: the PNG is square with empty margins top + bottom;
   a soft radial mask lets the map melt into the dotted page.
   .ct-map is only the layout box (and a size container for cqw).
   .ct-clip does the masking and bleeds --bx/--by past the box on every
   side, so parallax layers fade out instead of meeting a hard edge. The
   radial mask is the same ellipse as before, re-expressed in the clip's
   coordinates, so the look inside the map box is unchanged. */
.cities .ct-map{
  position:relative;width:min(100%,calc((100svh - var(--nav,72px) - 2 * var(--pad,48px) - 120px) * 10 / 9));
  aspect-ratio:10 / 9;margin:0 auto;
  container-type:inline-size;
  --mx:0; --my:0;
  --bx:44px; --by:44px;
}
.cities .ct-clip{
  position:absolute;
  inset:calc(-1 * var(--by)) calc(-1 * var(--bx));
  overflow:hidden;pointer-events:none;
  --ct-mask:radial-gradient(ellipse 82cqw 72cqw at calc(var(--bx) + 46cqw) calc(var(--by) + 45cqw),#000 74%,transparent 100%);
  -webkit-mask-image:var(--ct-mask),
    linear-gradient(to right,transparent,#000 var(--bx),#000 calc(100% - var(--bx)),transparent),
    linear-gradient(to bottom,transparent,#000 var(--by),#000 calc(100% - var(--by)),transparent);
  -webkit-mask-composite:source-in,source-in;
  mask-image:var(--ct-mask),
    linear-gradient(to right,transparent,#000 var(--bx),#000 calc(100% - var(--bx)),transparent),
    linear-gradient(to bottom,transparent,#000 var(--by),#000 calc(100% - var(--by)),transparent);
  mask-composite:intersect;
}
/* square stage — every overlay is positioned in % of this square,
   identical coordinate space to the original map wrap */
.cities .ct-stage{
  position:absolute;left:0;top:-5.5%;
  width:100%;aspect-ratio:1 / 1;
}
/* inside the clip: same place as the map box (top -5.5% of a 10:9 box = -4.95cqw) */
.cities .ct-clip > .ct-stage{
  left:var(--bx);top:calc(var(--by) - 4.95cqw);width:100cqw;
}
/* chips stage: unmasked, above the clip — chips + ticker can never be cut */
.cities .ct-stage-chips{z-index:4;pointer-events:none}
/* parallax layers: JS sets --mx/--my (-1..1) on desktop pointer move */
.cities .ct-layer{
  position:absolute;inset:0;
  transform:translate3d(calc(var(--mx) * var(--depth,0px)),calc(var(--my) * var(--depth,0px)),0);
  transition:transform .9s cubic-bezier(.22,1,.36,1);
}
.cities .ct-l-base{--depth:3px}
.cities .ct-l-land{--depth:6px}
.cities .ct-l-sea{--depth:5px}
.cities .ct-l-net{--depth:9px;z-index:3}
.cities .ct-l-chips{--depth:9px}
.cities .ct-l-sky{--depth:16px;z-index:5;pointer-events:none}
.cities .ct-l-base,.cities .ct-l-land,.cities .ct-l-sea{pointer-events:none}

.cities .ct-map-img{
  display:block;width:100%;height:100%;object-fit:contain;
  user-select:none;-webkit-user-drag:none;max-width:none;
  mix-blend-mode:multiply;
}

/* decorations — atmosphere, not data */
.cities .ct-deco{
  position:absolute;height:auto;max-width:none;
  user-select:none;pointer-events:none;-webkit-user-drag:none;
  opacity:.72;
}
/* trees + palm sway a few degrees from the trunk */
.cities .ct-sway{transform-origin:50% 100%;animation:ctSway 5.2s ease-in-out infinite alternate}
.cities .ct-sway-b{animation-duration:4.6s;animation-delay:-2.1s}
.cities .ct-sway-c{animation-duration:3.8s;animation-delay:-1.2s}
@keyframes ctSway{from{rotate:-3deg}to{rotate:3deg}}

/* waves drift side to side */
.cities .ct-wave{animation:ctWave 6.5s ease-in-out infinite alternate}
.cities .ct-wave-b{animation-duration:7.5s;animation-delay:-3s;animation-direction:alternate-reverse}
@keyframes ctWave{from{translate:-7% 0}to{translate:7% 0}}

/* boats cross the gulf (translate) and bob on the swell (transform) */
.cities .ct-boat{transform-origin:50% 90%}
.cities .ct-boat-l{animation:ctBoatDriftR 34s linear infinite,ctBob 3.4s ease-in-out infinite}
.cities .ct-boat-s{animation:ctBoatDriftL 28s linear infinite -9s,ctBob 2.8s ease-in-out infinite -1s}
@keyframes ctBoatDriftR{
  0%{translate:0 0;opacity:0}
  10%{opacity:.72} 88%{opacity:.72}
  100%{translate:170% 0;opacity:0}
}
@keyframes ctBoatDriftL{
  0%{translate:0 0;opacity:0}
  10%{opacity:.72} 88%{opacity:.72}
  100%{translate:-170% 0;opacity:0}
}
@keyframes ctBob{
  0%,100%{transform:translateY(0) rotate(-2.5deg)}
  50%{transform:translateY(-6%) rotate(2.5deg)}
}

/* plane layer — above everything */
.cities .ct-plane{
  position:absolute;inset:0;width:100%;height:100%;
  pointer-events:none;overflow:visible;
}
.cities .ct-plane-mark{will-change:transform,opacity}

/* routes layer */
.cities .ct-routes{
  position:absolute;inset:0;width:100%;height:100%;
  pointer-events:none;overflow:visible;
}
.cities .ct-paths path{
  fill:none;stroke:var(--ct-brand);stroke-width:.22;stroke-linecap:round;opacity:.95;
}
.cities .ct-flow circle{fill:var(--ct-brand)}
.cities .ct-city,
.cities .ct-hub{transform-box:fill-box;transform-origin:center}
.cities .ct-city-ring{fill:var(--ct-white);stroke:var(--ct-brand);stroke-width:.24}
.cities .ct-city-dot{fill:var(--ct-brand)}
.cities .ct-city-ping{
  fill:none;stroke:var(--ct-brand);stroke-width:.16;opacity:0;
  transform-box:fill-box;transform-origin:center;
}
.cities .ct-city.is-hot .ct-city-ping{animation:ctPing 1.3s var(--ct-ease) 2}
@keyframes ctPing{0%{transform:scale(.8);opacity:.7}100%{transform:scale(2.6);opacity:0}}

.cities .ct-hub-ring{fill:none;stroke:var(--ct-brand);stroke-width:.3}
.cities .ct-hub-dot{fill:var(--ct-brand)}
.cities .ct-hub-pulse{
  fill:none;stroke:var(--ct-brand);stroke-width:.18;
  transform-box:fill-box;transform-origin:center;
  animation:ctHubPulse 3.6s cubic-bezier(.2,.6,.35,1) infinite;
  will-change:transform,opacity;
}
.cities .ct-hub-pulse-2{animation-delay:-1.2s}
.cities .ct-hub-pulse-3{animation-delay:-2.4s}
@keyframes ctHubPulse{
  0%{transform:scale(.7);opacity:.65}
  100%{transform:scale(3.2);opacity:0}
}

/* city labels — name + small status */
.cities .ct-label{
  position:absolute;pointer-events:none;white-space:nowrap;
  display:flex;align-items:baseline;gap:6px;
  transform:translate(clamp(8px,1.2vw,13px),-50%);
  transform-origin:0 50%;
  text-shadow:0 0 3px #FEF9F2,0 0 3px #FEF9F2,0 0 6px #FEF9F2;
}
.cities .ct-label b{
  font:700 clamp(10.5px,1vw,13px)/1 Manrope,system-ui,sans-serif;
  letter-spacing:-.01em;color:var(--ct-ink);
}
.cities .ct-label i{
  font:800 clamp(8px,.7vw,9.5px)/1 Manrope,system-ui,sans-serif;font-style:normal;
  letter-spacing:.12em;text-transform:uppercase;color:var(--ct-muted);
  transition:color .3s ease;
}
.cities .ct-label.is-hot i{color:var(--ct-brand)}
/* Lagos — chip to the LEFT of the hub */
.cities .ct-label-lagos{
  align-items:center;gap:7px;
  padding:5px 8px 5px 10px;
  background:var(--ct-white);
  border:1.5px solid var(--ct-slab);border-radius:9px;
  box-shadow:2px 2px 0 var(--ct-slab);
  text-shadow:none;
  transform:translate(calc(-100% - clamp(10px,1.4vw,16px)),-50%);
  transform-origin:100% 50%;
}
.cities .ct-label-lagos b{font-family:Supreme,Manrope,sans-serif;font-weight:800;font-size:clamp(11px,1.05vw,14px)}
.cities .ct-label-lagos i,
.cities .ct-label-lagos.is-hot i{
  display:inline-flex;align-items:center;gap:4px;
  padding:3px 6px;border-radius:6px;
  background:var(--ct-brand);color:#FFF8F4;
}
.cities .ct-label-lagos i::before{
  content:"";width:5px;height:5px;border-radius:50%;background:#FFF8F4;
  animation:ctLiveBlink 1.7s ease-in-out infinite;
}
@keyframes ctLiveBlink{0%,100%{opacity:1}50%{opacity:.25}}

/* live ticker — hangs under the Lagos chip, cycles plain facts */
.cities .ct-ticker{
  position:absolute;pointer-events:none;
  display:flex;align-items:center;gap:7px;
  height:28px;padding:0 12px 0 9px;z-index:6;
  background:var(--ct-dark);color:#FAFAF8;
  border:1.5px solid var(--ct-slab);border-radius:8px;
  box-shadow:2px 2px 0 var(--ct-brand);
  /* right-anchored to the hub; max() keeps it (plus 9px of parallax) inside the 16px page gutter on narrow maps */
  transform:translate(max(calc(-100% - clamp(10px,1.4vw,16px)),calc(-26cqw - 3px)),calc(clamp(14px,1.3vw,18px) + 8px));
  font:600 11.5px/1 Manrope,system-ui,sans-serif;white-space:nowrap;
}
.cities .ct-tick-dot{
  flex:none;width:8px;height:8px;border-radius:50%;
  border:1.5px solid var(--ct-brand);background:transparent;
  transition:background .3s ease;
}
.cities .ct-tick-dot.is-live{background:var(--ct-brand)}
.cities .ct-tick-win{display:block;flex:none;overflow:hidden;height:16px;line-height:16px}
.cities .ct-tick-txt{white-space:nowrap}
.cities .ct-tick-txt{
  display:block;line-height:14px;
  transition:transform .35s var(--ct-ease),opacity .35s var(--ct-ease);
}
.cities .ct-tick-txt b{font-weight:800}
.cities .ct-tick-txt.is-out{transform:translateY(-100%);opacity:0}
.cities .ct-tick-txt.is-pre{transform:translateY(100%);opacity:0;transition:none}

/* key */
.cities .ct-key{
  position:absolute;left:14px;top:14px;z-index:6;
  display:flex;gap:12px;align-items:center;
  padding:7px 11px;
  background:var(--ct-white);
  border:1.5px solid var(--ct-slab);border-radius:10px;
  box-shadow:2px 2px 0 var(--ct-slab);
  font:800 10px/1 Manrope,system-ui,sans-serif;letter-spacing:.12em;text-transform:uppercase;color:var(--ct-ink);
}
.cities .ct-key span{display:inline-flex;align-items:center;gap:6px}
.cities .ct-key i{display:block;width:9px;height:9px;border-radius:50%}
.cities .ct-key-live{background:var(--ct-brand);box-shadow:0 0 0 2px var(--ct-peach)}
.cities .ct-key-next{background:var(--ct-white);border:1.5px solid var(--ct-brand)}

/* ---------- staged reveal (JS adds .ct-armed, then .ct-in) ----------
   no JS / reduced motion: neither class, everything simply shows.
   Timeline: copy rises, tiles pop in one by one, the map fades up, the
   Lagos hub lands, then each route draws out from Lagos (nearest first)
   and its city + label pop in as the line arrives. */
.cities{--ct-r0:1.15s; --ct-rstep:.42s; --ct-rdraw:.7s}

.cities.ct-armed .ct-copy > :not(.ct-tiles){opacity:0;transform:translateY(14px)}
.cities.ct-armed .ct-tile{opacity:0;transform:translateY(16px) scale(.94)}
.cities.ct-armed .ct-card{opacity:0;transform:translateY(22px)}
.cities.ct-armed .ct-map-img,
.cities.ct-armed .ct-deco:not(.ct-boat),
.cities.ct-armed .ct-flow,
.cities.ct-armed .ct-city,
.cities.ct-armed .ct-hub,
.cities.ct-armed .ct-label,
.cities.ct-armed .ct-ticker,
.cities.ct-armed .ct-key{opacity:0}
.cities.ct-armed .ct-paths path{stroke-dasharray:100 120;stroke-dashoffset:101}

.cities.ct-in .ct-copy > :not(.ct-tiles),
.cities.ct-in .ct-card{
  opacity:1;transform:none;
  transition:opacity .7s var(--ct-ease),transform .7s var(--ct-ease);
}
.cities.ct-in .ct-copy > :nth-child(2){transition-delay:.08s}
.cities.ct-in .ct-copy > :nth-child(3){transition-delay:.16s}
.cities.ct-in .ct-card{transition-delay:.1s}

.cities.ct-in .ct-tile{
  opacity:1;transform:none;
  transition:opacity .45s var(--ct-ease) calc(.32s + var(--i) * .12s),
             transform .55s var(--ct-pop) calc(.32s + var(--i) * .12s),
             box-shadow .18s var(--ct-ease);
}
/* hover must not wait for the reveal delay */
/* once in, each tile's icon gives a small hop in turn */
.cities.ct-in .ct-tile-ico{animation:ctHop 9s var(--ct-ease) infinite;animation-delay:calc(3.6s + var(--i) * 2.25s)}
@keyframes ctHop{
  0%,9%,100%{transform:none}
  3%{transform:translateY(-3px) rotate(-6deg)}
  6%{transform:translateY(0) rotate(3deg)}
}

.cities.ct-in .ct-map-img{opacity:1;transition:opacity .9s var(--ct-ease) .2s}
.cities.ct-in .ct-deco:not(.ct-boat){opacity:.72;transition:opacity 1s var(--ct-ease) .5s}
.cities.ct-in .ct-hub{opacity:1;animation:ctPopIn .55s var(--ct-pop) .85s both}
.cities.ct-in .ct-label-lagos{animation:ctLabelIn .5s var(--ct-pop) .95s both}

.cities.ct-in .ct-paths path{
  stroke-dashoffset:0;
  transition:stroke-dashoffset var(--ct-rdraw) cubic-bezier(.45,0,.25,1) calc(var(--ct-r0) + var(--d) * var(--ct-rstep));
}
.cities.ct-in .ct-city{
  opacity:1;
  animation:ctPopIn .5s var(--ct-pop) calc(var(--ct-r0) + var(--ct-rdraw) - .08s + var(--d) * var(--ct-rstep)) both;
}
.cities.ct-in .ct-label:not(.ct-label-lagos){
  animation:ctLabelIn .5s var(--ct-pop) calc(var(--ct-r0) + var(--ct-rdraw) + var(--d) * var(--ct-rstep)) both;
}
.cities.ct-in .ct-key{opacity:1;transition:opacity .55s var(--ct-ease) 2.9s}
.cities.ct-in .ct-flow{opacity:1;transition:opacity .8s var(--ct-ease) 3.1s}
.cities.ct-in .ct-ticker{animation:ctLabelIn .5s var(--ct-pop) 3.2s both}

@keyframes ctPopIn{
  0%{opacity:0;transform:scale(0)}
  100%{opacity:1;transform:scale(1)}
}
/* labels keep their offset transform; the bounce rides on `scale` */
@keyframes ctLabelIn{
  0%{opacity:0;scale:.55}
  60%{opacity:1;scale:1.08}
  100%{opacity:1;scale:1}
}

/* ---------- responsive ---------- */
@media (max-width:900px){
  .cities{padding:64px 0}
  .cities .ct-grid{grid-template-columns:1fr;gap:28px}
  .cities .ct-copy{max-width:560px}
  .cities .ct-facts{grid-template-columns:repeat(2,minmax(0,1fr))}
  .cities .ct-tile:nth-child(3){padding-left:0;border-left:0}
  .cities .ct-map{width:100%}
}
@media (max-width:560px){
  .cities .ct-facts{grid-template-columns:1fr}
  .cities .ct-tile,.cities .ct-tile + .ct-tile{padding:12px 0;border-left:0;border-bottom:1px solid rgba(42,33,26,.25)}
  .cities .ct-tile b{font-size:17px}
  /* zoom the stage so Nigeria fills the narrow width */
  .cities .ct-map{
    aspect-ratio:1 / 1;
    /* full-width map: a wider, gentler fade so the Lagos chips stay crisp */
  }
  /* bleed only as far as the 16px page gutter on a phone */
  .cities .ct-map{--bx:16px;--by:24px}
  .cities .ct-clip{
    --ct-mask:radial-gradient(ellipse 85cqw 76cqw at calc(var(--bx) + 50cqw) calc(var(--by) + 46cqw),#000 70%,transparent 100%);
  }
  .cities .ct-stage{width:100%;left:0;top:-4%}
  .cities .ct-clip > .ct-stage{left:var(--bx);top:calc(var(--by) - 4cqw);width:100cqw}
  .cities .ct-ticker{display:none}
  .cities .ct-key{left:10px;top:10px;padding:6px 9px;gap:10px;font-size:9px}
  .cities .ct-label{gap:4px}
  .cities .ct-label b{font-size:10.5px}
  .cities .ct-label i{font-size:7.5px;letter-spacing:.1em}
  .cities .ct-label-lagos{padding:4px 6px 4px 7px;gap:5px;border-radius:8px}
  .cities .ct-label-lagos b{font-size:11px}
  /* no room left of the hub on a phone: hang the chip just below it */
  .cities .ct-label-lagos{transform:translate(-50%,13px);transform-origin:50% 0}
  .cities .ct-label-lagos i{padding:2px 4px}
  .cities .ct-ticker{transform:translate(-50%,44px);height:22px;font-size:10px;gap:6px;padding:0 8px 0 6px}
  .cities .ct-tick-dot{width:7px;height:7px}
}

@media (prefers-reduced-motion:reduce){
  .cities .ct-boat,.cities .ct-sway,.cities .ct-wave{animation:none}
  .cities .ct-l-sky{display:none}
  .cities .ct-hub-pulse,.cities .ct-flow,.cities .ct-city-ping{display:none}
  .cities .ct-label-lagos i::before{animation:none}
  .cities .ct-tile,.cities .ct-layer{transition:none}
  .cities .ct-tile-ico{animation:none}
}
