:root{
  --cream:#FAF6F1;
  --white:#FFFFFF;
  --sand:#EFE6DC;
  --brown:#5D4037;
  --ink:#2B1F1A;
  --ink-soft:#5A4A41;
  --ink-mid:#4A3B33;
  --label:#756253;
  --green:#1F4D3A;
  --green-dark:#16382A;
  --green-soft:#DCE8E1;
  --green-label:#B7CCC1;
  --line:#EDE3D9;
  --line-mid:#E4D8CC;
  --line-sand:#E0D2C4;
  --field:#C9B8A8;
  --on-brown:#EFE4DA;
  --rule-brown:rgba(247,240,233,.3);
  --foot:#B9A596;
  --foot-dim:#9C8B7D;
  --foot-mark:#F0E7DE;
  --wrap:1140px;
  --pad:clamp(20px,4vw,32px);
  --band:clamp(64px,7vw,96px);
}

*{box-sizing:border-box}
html,body{margin:0;padding:0}
html{background:var(--cream);scroll-behavior:smooth}
body{
  background:var(--cream);
  color:var(--ink);
  font-family:"Libre Franklin","Helvetica Neue",Helvetica,Arial,sans-serif;
  font-size:18px;
  line-height:1.6;
  -webkit-font-smoothing:antialiased;
  overflow-x:hidden;
  /* The page is one screen: the hero takes whatever the nav and footer leave,
     so the footer always sits on the bottom edge and never floats above a
     strip of empty page on a tall monitor. */
  min-height:100vh;min-height:100svh;
  display:flex;flex-direction:column;
}
main{flex:1 0 auto;display:flex}
img{display:block;width:100%;height:auto}
ul{margin:0;padding:0;list-style:none}

a{color:var(--green);text-decoration:none}
a:hover{color:var(--green-dark);text-decoration:underline}
a:focus-visible,select:focus-visible{outline:3px solid var(--green);outline-offset:3px}
.band-brown a:focus-visible,.band-green a:focus-visible{outline-color:#FFFFFF}

.skip{
  position:absolute;left:-9999px;top:0;z-index:100;
  background:var(--green);color:#FFFFFF;padding:12px 18px;border-radius:0 0 12px 0;
}
.skip:focus{left:0;text-decoration:none}

.wrap{max-width:var(--wrap);margin:0 auto;padding-left:var(--pad);padding-right:var(--pad)}

/* ---------- navigation ---------- */
.nav{position:sticky;top:0;z-index:50;width:100%;background:var(--cream);transition:box-shadow 250ms ease-out}
.nav.is-scrolled{box-shadow:0 2px 20px rgba(43,31,26,.14)}
.nav-inner{
  max-width:var(--wrap);margin:0 auto;padding:16px var(--pad);
  display:flex;align-items:center;justify-content:space-between;gap:20px;flex-wrap:wrap;
}
.wordmark{font-size:18px;font-weight:700;letter-spacing:-.01em;color:var(--brown)}
.nav-links{display:flex;align-items:center;gap:clamp(16px,2vw,32px);flex-wrap:wrap}
.nav-link{font-size:16px;font-weight:500;color:var(--ink-mid)}
.nav-link:hover{color:var(--ink);text-decoration:none}

/* ---------- buttons and fields ---------- */
.btn{
  display:inline-flex;align-items:center;justify-content:center;
  font-weight:600;border-radius:14px;
  transition:transform 150ms ease-out,background 150ms ease-out;
}
.btn:hover{text-decoration:none;transform:translateY(-2px)}
.btn-sm{height:44px;padding:0 20px;font-size:15px}
.btn-lg{height:54px;padding:0 20px;font-size:17px;width:100%}
.btn-green{background:var(--green);color:#FFFFFF}
.btn-green:hover{background:var(--green-dark);color:#FFFFFF}
.btn-cream{background:var(--cream);color:var(--green)}
.btn-cream:hover{background:#FFFFFF;color:var(--green-dark)}

.label{
  display:block;font-size:14px;font-weight:500;
  letter-spacing:.06em;text-transform:uppercase;color:var(--label);
}
.label-green{color:var(--green-label)}
.select{
  margin-top:10px;width:100%;height:54px;padding:0 14px;
  font-family:inherit;font-size:17px;font-weight:500;color:var(--ink);
  background:var(--white);border:1px solid var(--field);border-radius:14px;
}
.band-green .select{border-color:#7FA394}
.chooser{margin-top:36px;max-width:400px}
.chooser .btn-lg{margin-top:16px}
.chooser-centred{margin-left:auto;margin-right:auto;width:100%;text-align:left}
.underlink{
  display:inline-block;margin-top:16px;font-size:16px;font-weight:500;
  color:var(--brown);border-bottom:1px solid #C9B4A6;
}
.underlink:hover{color:var(--ink);text-decoration:none}

/* ---------- typography ---------- */
h1{
  margin:0;max-width:16ch;
  font-size:clamp(34px,4.2vw,56px);line-height:1.08;letter-spacing:-.025em;
  font-weight:700;color:var(--ink);text-wrap:pretty;
}
h2{
  margin:0;
  font-size:clamp(28px,3vw,36px);line-height:1.2;letter-spacing:-.02em;
  font-weight:700;color:var(--ink);text-wrap:pretty;
}
h3{margin:16px 0 0;font-size:22px;line-height:1.3;font-weight:600;color:var(--ink)}
p{margin:0;text-wrap:pretty}
.lead{margin-top:24px;max-width:54ch;color:var(--ink-soft)}
.measure{max-width:760px}
.measure h2{max-width:22ch}
.measure p{margin-top:20px;color:var(--ink-soft)}
.measure .label + h2{margin-top:16px}
.fine{margin-top:20px;font-size:15px;line-height:1.55;color:var(--ink-mid)}
.on-brown{color:#FFFFFF;max-width:22ch}
.on-green{color:#FFFFFF}
.on-green-muted{margin-top:18px;max-width:46ch;color:var(--green-soft)}
.centred{display:flex;flex-direction:column;align-items:center;text-align:center}
.centred .chooser{width:100%;max-width:400px}

/* ---------- bands ---------- */
.band{width:100%;padding:var(--band) 0}
.band-white{background:var(--white)}
.band-cream{background:var(--cream)}
.band-sand{background:var(--sand)}
.band-brown{background:var(--brown);color:var(--on-brown)}
.band-green{background:var(--green);color:#FFFFFF}

/* ---------- hero ---------- */
.hero{width:100%;background:var(--cream);display:flex;align-items:center;padding:clamp(28px,6vh,80px) 0}
.hero > .wrap{width:100%}
.hero-grid{display:flex;flex-wrap:wrap;gap:clamp(40px,4vw,56px);align-items:center}
.hero-grid > *:first-child{flex:1 1 520px;min-width:0}
.hero-copy{max-width:600px}
/* The headline needs about 560px to sit on four lines at this size. At 56px it
   needed 624px, which squeezed the map back to a thumbnail; at 50px both fit. */
.hero h1{font-size:clamp(34px,4.2vw,50px)}
.hero-shot{flex:1 1 400px;max-width:560px;min-width:0;display:flex;justify-content:center;align-items:center}

/* ---------- device frames ---------- */
.phone{
  width:340px;max-width:100%;border-radius:38px;background:var(--ink);padding:10px;
  box-shadow:0 40px 70px -40px rgba(43,31,26,.55);
}
.phone-screen{border-radius:29px;overflow:hidden;background:var(--white)}
.phone-sm{width:300px;border-radius:34px;padding:9px;box-shadow:0 30px 56px -34px rgba(43,31,26,.5)}
.phone-sm .phone-screen{border-radius:26px}
.browser{
  margin:0;border-radius:12px;overflow:hidden;background:var(--white);
  border:1px solid var(--line-mid);box-shadow:0 24px 48px -28px rgba(43,31,26,.45);
}
.browser-sand{border-color:var(--line-sand)}
.browser-bar{
  display:flex;align-items:center;gap:7px;padding:11px 14px;
  background:#F3ECE4;border-bottom:1px solid var(--line-mid);
}
.browser-sand .browser-bar{background:#F7F1EA;border-bottom-color:var(--line-sand)}
.browser-bar span{width:10px;height:10px;border-radius:50%;background:#D6C4B4;display:block}

/* ---------- problem columns ---------- */
.cols-3{
  margin-top:clamp(36px,4vw,56px);
  display:grid;grid-template-columns:repeat(auto-fit,minmax(260px,1fr));
  gap:clamp(28px,3vw,48px);
}
.ruled{padding-top:20px;border-top:1px solid var(--rule-brown);color:var(--on-brown)}

/* ---------- steps ---------- */
.band-white h2{margin-bottom:clamp(40px,4vw,64px)}
.step{border-bottom:1px solid var(--line)}
.step-plain{max-width:640px;padding-bottom:clamp(40px,4vw,64px)}
.step-split{
  display:flex;flex-wrap:wrap;gap:clamp(32px,4vw,64px);align-items:center;
  padding:clamp(40px,4vw,64px) 0;
}
.step-reverse{flex-wrap:wrap-reverse}
.step-last{padding-bottom:0;border-bottom:0}
.step-text{flex:1 1 300px;min-width:0}
.step-shot{flex:1 1 380px;min-width:0}
.step-shot-phone{flex:0 1 340px;display:flex;justify-content:center}
.stepnum{font-size:44px;line-height:1;font-weight:700;color:#9E8B7C;transition:color 500ms ease-out}
.is-shown .stepnum{color:var(--green)}
.step-text p{margin-top:10px;color:var(--ink-soft)}

/* ---------- split band ---------- */
.split{display:flex;flex-wrap:wrap;gap:clamp(32px,4vw,64px);align-items:center}
.split-text{flex:1 1 380px;min-width:0}
.split-text h2{max-width:18ch}
.split-text p{margin-top:24px;max-width:56ch;color:var(--ink-mid)}
.split-shot{flex:1 1 420px;min-width:0}
.wide-shot{margin-top:clamp(40px,4vw,56px)}
.wide-shot .browser{box-shadow:0 32px 64px -32px rgba(43,31,26,.45)}

/* ---------- tally ---------- */
.tally{margin-top:clamp(28px,3vw,44px)}
.tally li{padding:20px 0;border-top:1px solid var(--rule-brown);color:var(--on-brown)}
.tally li:last-child{border-bottom:1px solid var(--rule-brown)}

/* ---------- footer ---------- */
.footer{width:100%;background:var(--ink);color:var(--foot);padding:clamp(40px,5vw,64px) 0;flex-shrink:0}
.footer-top{
  display:flex;flex-wrap:wrap;gap:20px;justify-content:space-between;align-items:center;
  padding-bottom:28px;border-bottom:1px solid rgba(185,165,150,.25);
}
.footer-mark{font-size:16px;font-weight:600;color:var(--foot-mark)}
.footer-copy{font-size:14px;color:var(--foot-dim)}
.footer-legal{margin-top:28px;max-width:78ch}
.footer-legal p{font-size:14px;line-height:1.6;color:var(--foot-dim)}
.footer-legal p + p{margin-top:12px}

/* ---------- motion ---------- */
.reveal{opacity:1}
.js .reveal{opacity:0;transform:translateY(16px);transition:opacity 500ms ease-out,transform 500ms ease-out}
.js .reveal.is-shown{opacity:1;transform:none}

@media (prefers-reduced-motion:reduce){
  html{scroll-behavior:auto}
  .js .reveal{opacity:1;transform:none;transition:none}
  .btn:hover{transform:none}
  .stepnum{color:var(--green)}
}

@media (max-width:700px){
  body{font-size:17px}
  .nav-inner{padding:12px var(--pad)}
  .nav-link{font-size:15px}
  .phone{width:300px}
  .step-shot-phone{flex:1 1 100%}
}

/* ------------------------------------------------------- inactive button
   The country button does nothing until a country with a site is chosen. */
.btn.is-inactive{
  background:var(--sand);
  color:var(--label);
  cursor:not-allowed;
  pointer-events:none;
}
.btn.is-inactive:hover{transform:none}

/* The gateway footer is the mark and the copyright only: no rule beneath it,
   because there is no longer anything under it to separate. */
.footer-bare{padding-bottom:0;border-bottom:0}
.footer:has(.footer-bare){padding:22px 0}

/* ------------------------------------------------------------ africa mesh
   The hero picture: the continent as a quiet triangular web, with the
   countries that are live on the platform picked out in the live colour.
   Generated by tools/build_africa_mesh.py.

   It has one entrance and three responses, and nothing else moves:
   - entrance: the continent settles in, then Ghana lights, in that order,
     because that order is the whole message;
   - under the pointer the web turns green, as if lit, fading at the edge;
   - hovering or focusing a live country brightens it and names it;
   - choosing a country, on the map or in the list, sends one ring out from it.
   All of it stops for anyone who has asked for reduced motion. */
.africa{
  display:block;width:100%;height:auto;overflow:visible;
  /* Never taller than the room the screen leaves for it. */
  max-height:min(640px,calc(100svh - 250px));
}
.land{fill:rgba(93,64,55,.055)}
.web{fill:none;stroke:rgba(93,64,55,.22);stroke-width:.5;vector-effect:non-scaling-stroke}
.dots{fill:rgba(93,64,55,.36)}
.pulse circle{fill:rgba(93,64,55,.36);animation:mesh-breathe 5.2s ease-in-out infinite}
/* The stagger lives here, not in style attributes: the site's policy is
   style-src 'self', which blocks inline styles. Coprime steps and differing
   durations keep neighbours out of step, and the phases drift apart over time
   rather than falling back into unison. Negative delays start them mid-breath. */
.pulse circle:nth-child(2n){animation-duration:6.3s}
.pulse circle:nth-child(5n){animation-duration:4.4s}
.pulse circle:nth-child(3n){animation-delay:-1.7s}
.pulse circle:nth-child(3n+1){animation-delay:-3.4s}
.pulse circle:nth-child(7n+3){animation-delay:-4.9s}
.pulse circle:nth-child(11n+5){animation-delay:-.8s}
@keyframes mesh-breathe{0%,100%{opacity:.35}50%{opacity:1}}

/* Entrance. */
.land,.web,.dots,.pulse{animation:mesh-in 900ms ease-out both}
.live{
  transform-box:fill-box;transform-origin:center;
  animation:live-in 700ms 650ms cubic-bezier(.2,.8,.2,1) both;
}
@keyframes mesh-in{from{opacity:0}to{opacity:1}}
@keyframes live-in{from{opacity:0;transform:scale(.55)}to{opacity:1;transform:none}}

/* The lens: the same web in the live colour, seen only around the pointer.
   A faint green tint over cream read as grey dirt; lighting the lines reads
   as light, and says what green means on this map. */
.lit{opacity:0;transition:opacity 350ms ease-out;pointer-events:none}
.africa.is-lit .lit{opacity:1}
.lit-web{fill:none;stroke:var(--green);stroke-width:1}
.lit-dots{fill:var(--green)}

/* A live country. */
.live{cursor:pointer;outline:none}
.live-halo{
  fill:url(#glow);
  transform-box:fill-box;transform-origin:center;
  animation:mesh-halo 6s ease-in-out infinite;
  transition:opacity 250ms ease-out;
}
@keyframes mesh-halo{0%,100%{transform:scale(.88);opacity:.75}50%{transform:scale(1.06);opacity:1}}
.live-fill{fill:rgba(31,77,58,.24);transition:fill 250ms ease-out}
.live-web{fill:none;stroke:rgba(31,77,58,.65);stroke-width:.5;vector-effect:non-scaling-stroke}
.live-dots{fill:var(--green)}
.live-edge{
  fill:none;stroke:var(--green);stroke-width:2.2;
  vector-effect:non-scaling-stroke;stroke-linejoin:round;
  transition:stroke-width 200ms ease-out;
}
.live-label{
  font-size:19px;font-weight:600;letter-spacing:-.01em;
  fill:var(--green);opacity:0;
  transform:translateY(-4px);transition:opacity 220ms ease-out,transform 220ms ease-out;
  pointer-events:none;
}
.live-ping{
  fill:none;stroke:var(--green);stroke-width:1.5;vector-effect:non-scaling-stroke;
  opacity:0;transform-box:fill-box;transform-origin:center;pointer-events:none;
}

.live:hover .live-fill,.live:focus-visible .live-fill,.live.is-chosen .live-fill{fill:rgba(31,77,58,.42)}
.live:hover .live-edge,.live:focus-visible .live-edge,.live.is-chosen .live-edge{stroke-width:3}
.live:hover .live-label,.live:focus-visible .live-label,.live.is-chosen .live-label{opacity:1;transform:none}
/* Keyboard focus needs more than a colour change to be seen. */
.live:focus-visible .live-ping{opacity:.5;stroke-dasharray:3 3}
.live.is-pinging .live-ping{animation:live-ping 1100ms cubic-bezier(.2,.7,.3,1)}
@keyframes live-ping{0%{opacity:.8;transform:scale(.5)}100%{opacity:0;transform:scale(2.6)}}

/* Small laptops: tighten the copy so the hero still fits on one screen. */
@media (min-width:900px) and (max-height:780px){
  .hero h1{font-size:clamp(32px,3.5vw,46px)}
  .lead{margin-top:16px}
  .chooser{margin-top:24px}
}

@media (prefers-reduced-motion:reduce){
  .pulse circle,.live-halo,.land,.web,.dots,.pulse,.live{animation:none}
  .live.is-pinging .live-ping{animation:none}
  .lit{display:none}
}
