/* =============================================================================
   The network: the three factories on the regional map, one card for each
   (views/partials/network.php). About's Regional Presence chapter and the
   Contact page use it.

   The map is the one behind the home hero's third slide, drawn by
   tools/region-map.php, and the pins are placed by the same projection from
   config/site.php, so the two never disagree. The map is geography: it is
   never mirrored for Arabic, so it is laid out with physical left/top; the
   words around it follow the page direction.
   ========================================================================== */

.network {
  --net-bg: var(--eme-night);
  --net-card: #121517;
  --net-card-on: #171b1e;
  --net-line: rgba(255, 255, 255, 0.1);
  --net-muted: #a3a9ae;
  --net-soft: rgba(255, 255, 255, 0.86);
  position: relative;
  padding-block: var(--eme-section);
  background: var(--net-bg);
  color: var(--eme-white);
  overflow-x: clip;
}

/* The page opens on it (Contact): the header floats over the map, so the
   heading starts below its row, as a cover page's does. */
.network--hero {
  padding-block-start: calc(
    var(--eme-over-pad) + clamp(68px, 3.5rem + 1vw, 88px) +
      clamp(1.5rem, 5vw, 4rem)
  );
}

.network__head {
  position: relative;
  z-index: 2;
}
.network__head .home-head {
  margin: 0;
}

/* ------------------------------------------------------------------ the map
   A full-bleed band. The plate keeps the drawing's proportions and is scaled
   and placed so the factories sit where this band wants them: --z is the
   plate's width as a multiple of the band's, --px/--py where the middle of the
   factories lands in the band. The band fades at every edge, so the head above
   it and the cards below it sit on the same night as the sea. */
.network__map {
  --z: 1.65;
  --px: 54%;
  --py: 45%;
  position: relative;
  z-index: 1;
  aspect-ratio: 1.45;
  margin-block: clamp(-2.5rem, -4vw, -1rem) 0;
  overflow: hidden;
  -webkit-mask-image:
    linear-gradient(
      180deg,
      transparent 0%,
      #000 17%,
      #000 78%,
      transparent 100%
    ),
    linear-gradient(90deg, transparent 0%, #000 7%, #000 93%, transparent 100%);
  -webkit-mask-composite: source-in;
  mask-image:
    linear-gradient(
      180deg,
      transparent 0%,
      #000 17%,
      #000 78%,
      transparent 100%
    ),
    linear-gradient(90deg, transparent 0%, #000 7%, #000 93%, transparent 100%);
  mask-composite: intersect;
}
.network__plate {
  position: absolute;
  left: var(--px);
  top: var(--py);
  width: calc(var(--z) * 100%);
  aspect-ratio: var(--ratio);
  transform: translate(calc(var(--cx) * -1%), calc(var(--cy) * -1%));
}
.network__land,
.network__overlay {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  max-width: none;
}
.network__overlay {
  overflow: visible;
}
.network__overlay path {
  vector-effect: non-scaling-stroke;
}

.network__country {
  fill: rgb(218 33 39 / 0.15);
  stroke: rgb(218 33 39 / 0.55);
  stroke-width: 1;
  stroke-linejoin: round;
  transition:
    fill var(--eme-med) var(--eme-ease),
    stroke var(--eme-med) var(--eme-ease);
}
.network__route {
  fill: none;
  stroke: var(--eme-red);
  stroke-width: 1.5;
  stroke-linecap: round;
  stroke-dasharray: 1;
  stroke-dashoffset: 0;
  transition: stroke-opacity var(--eme-med) var(--eme-ease);
}
/* What travels the routes: a short bright stroke from head office out to the
   factory it supplies, over and over. */
.network__flow {
  fill: none;
  stroke: #ff8a8e;
  stroke-width: 2;
  stroke-linecap: round;
  stroke-dasharray: 0.07 0.93;
  stroke-dashoffset: 0.07;
  opacity: 0;
  animation: net-flow 4.2s cubic-bezier(0.45, 0, 0.25, 1) 2.6s infinite;
}
.network__flow + .network__route + .network__flow {
  animation-delay: 3.9s;
}

/* A pin is a point with no size at its coordinate; the dot is centred on it,
   the label hangs below, away from the routes arcing above. A generous round
   target makes it easy to point at. */
.network__pin {
  position: absolute;
  left: var(--x);
  top: var(--y);
  width: 0;
  height: 0;
  cursor: pointer;
}
.network__pin::before {
  content: "";
  position: absolute;
  left: -22px;
  top: -22px;
  width: 44px;
  height: 44px;
  border-radius: 50%;
}
.network__dot {
  position: absolute;
  left: 0;
  top: 0;
  width: 10px;
  height: 10px;
  border-radius: 50%;
  background: var(--eme-red);
  box-shadow: 0 0 0 3px rgb(218 33 39 / 0.25);
  transform: translate(-50%, -50%);
  transition: transform var(--eme-med) var(--eme-ease-out);
}
.network__pin--hq .network__dot {
  width: 14px;
  height: 14px;
  background: var(--eme-white);
  box-shadow: 0 0 0 3px var(--eme-red);
}
.network__dot::after {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: 50%;
  border: 1px solid var(--eme-red);
  opacity: 0;
}
/* Head office keeps a slow pulse; a factory pulses while it is pointed at. */
.network__pin--hq .network__dot::after,
.network__pin.is-active .network__dot::after {
  animation: net-ping 2.8s var(--eme-ease-out) infinite;
}
.network__label {
  position: absolute;
  top: 12px;
  left: -3px;
  display: grid;
  gap: 1px;
  font-size: var(--eme-step--1);
  line-height: 1.3;
  color: rgb(255 255 255 / 0.66);
  text-align: left;
  text-shadow: 0 1px 10px rgb(0 0 0 / 0.95);
  white-space: nowrap;
  transition: color var(--eme-med) var(--eme-ease);
}
.network__pin--flip .network__label {
  left: auto;
  right: -3px;
  text-align: right;
}
.network__city {
  color: var(--eme-white);
  font-weight: 600;
  letter-spacing: 0.06em;
  text-transform: uppercase;
}
html[lang="ar"] .network__label {
  direction: rtl;
}
html[lang="ar"] .network__city {
  letter-spacing: 0;
}

/* One factory in focus: its country, route and pin come forward, the others
   step back. */
.network.has-active .network__country {
  fill: rgb(218 33 39 / 0.06);
  stroke: rgb(218 33 39 / 0.28);
}
.network.has-active .network__country.is-active {
  fill: rgb(218 33 39 / 0.3);
  stroke: rgb(255 90 95 / 0.95);
}
.network.has-active .network__route:not(.is-active) {
  stroke-opacity: 0.3;
}
.network.has-active .network__flow:not(.is-active) {
  visibility: hidden;
}
/* Head office in focus: every route starts there, so every route stays lit. */
.network:has(.network__pin--hq.is-active) .network__route {
  stroke-opacity: 1;
}
.network:has(.network__pin--hq.is-active) .network__flow {
  visibility: visible;
}
.network.has-active .network__pin:not(.is-active) .network__label {
  color: rgb(255 255 255 / 0.4);
}
.network.has-active .network__pin:not(.is-active) .network__city {
  color: rgb(255 255 255 / 0.55);
}
.network__pin.is-active .network__dot {
  transform: translate(-50%, -50%) scale(1.3);
}
.network__pin.is-active .network__label {
  color: var(--net-soft);
}

/* ---------------------------------------------------------------- the cards
   One ledger docked into the foot of the map: three columns, the hairlines
   between them are the list's own ground showing through the gaps. */
.network__dock {
  position: relative;
  z-index: 2;
}
.network__list {
  display: grid;
  gap: 1px;
  margin: clamp(-4.5rem, -5vw, -1.25rem) 0 0;
  padding: 0;
  list-style: none;
  background: var(--net-line);
  border: 1px solid var(--net-line);
}
.nc {
  position: relative;
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  align-content: start;
  row-gap: var(--eme-space-5);
  padding: clamp(1.5rem, 1rem + 1.4vw, 2.25rem);
  background: var(--net-card);
  transition: background-color var(--eme-med) var(--eme-ease);
}
/* The card in focus: a red rule runs along its top edge. */
.nc::before {
  content: "";
  position: absolute;
  inset-inline: -1px;
  inset-block-start: -1px;
  block-size: 2px;
  background: var(--eme-red);
  transform: scaleX(0);
  transform-origin: 0 50%;
  transition: transform 520ms var(--eme-ease-out);
}
html[dir="rtl"] .nc::before {
  transform-origin: 100% 50%;
}
.nc.is-active {
  background: var(--net-card-on);
}
.nc.is-active::before {
  transform: scaleX(1);
}

.nc__id {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr);
  align-content: start;
  align-items: center;
  column-gap: 0.85rem;
}
/* The pin, drawn the way the map draws it. */
.nc__mark {
  grid-row: 1;
  inline-size: 10px;
  block-size: 10px;
  border-radius: 50%;
  background: var(--eme-red);
  box-shadow: 0 0 0 3px rgb(218 33 39 / 0.25);
}
.nc--hq .nc__mark {
  inline-size: 12px;
  block-size: 12px;
  background: var(--eme-white);
  box-shadow: 0 0 0 3px var(--eme-red);
}
.nc__name {
  grid-row: 1;
  margin: 0;
  font-size: var(--eme-step-4);
  font-weight: 700;
  line-height: 1.1;
  letter-spacing: -0.015em;
  color: var(--eme-white);
}
html[lang="ar"] .nc__name {
  line-height: 1.4;
  letter-spacing: 0;
}
.nc__role {
  grid-column: 2;
  margin: 0.35rem 0 0;
  font-size: var(--eme-step-0);
  line-height: 1.45;
  color: var(--net-muted);
  margin-inline-start: -30px;
}
.nc__place,
.nc__address {
  margin: 0;
  font-style: normal;
  line-height: 1.55;
  color: var(--net-soft);
}

/* Profile: size and year side by side, the market on a row of its own; three
   across once a card is wide enough (below). */
.nc__facts {
  display: grid;
  grid-template-columns: auto auto;
  justify-content: start;
  gap: var(--eme-space-4) clamp(1.25rem, 0.8rem + 1.2vw, 2.25rem);
  margin: 0;
  padding-block: var(--eme-space-4);
  border-block: 1px solid var(--net-line);
}
.nc__facts > div {
  display: grid;
  gap: 0.15rem;
}
.nc__facts dt {
  font-size: var(--eme-step--1);
  color: var(--net-muted);
}
.nc__facts dd {
  margin: 0;
  font-size: var(--eme-step-1);
  font-weight: 600;
  line-height: 1.35;
  color: var(--eme-white);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}
.nc__market {
  grid-column: 1 / -1;
}
.nc__market dd {
  white-space: normal;
}

/* Contact: the ways in, one per line. The links are named through the card
   (.nc a) so they outrank site.css's touch rule for tel:/mailto: links, which
   would otherwise set them inline-block and drop the icon onto its own line;
   they carry their own finger-sized rows instead. */
.nc__reach {
  display: grid;
  gap: 0.4rem;
  margin: 0;
  padding: var(--eme-space-4) 0;
  list-style: none;
  border-block: 1px solid var(--net-line);
}
.nc .nc__reach a,
.nc a.nc__call {
  display: inline-flex;
  align-items: center;
  gap: 0.65rem;
  min-block-size: 2.25rem;
  padding-block: 0;
  font-weight: 500;
  color: var(--eme-white);
  overflow-wrap: anywhere;
  transition: color var(--eme-fast) var(--eme-ease);
}
.nc__reach svg,
.nc__call svg {
  flex: none;
  color: var(--eme-red);
}
.nc__reach a:hover,
.nc__call:hover {
  color: #ff8a8e;
}
.nc .nc__reach a[href^="tel:"],
.nc a.nc__call {
  direction: inherit;
  font-variant-numeric: tabular-nums;
}
@media (pointer: coarse) {
  .nc .nc__reach a,
  .nc a.nc__call,
  .nc .nc__go {
    min-block-size: 2.75rem;
  }
  .nc__reach {
    gap: 0.1rem;
  }
}

.nc__actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: var(--eme-space-3) var(--eme-space-5);
}
.nc__serves {
  margin: 0;
  font-size: var(--eme-step--1);
  color: var(--net-muted);
}
.nc__serves strong {
  display: block;
  margin-block-start: 0.1rem;
  font-size: var(--eme-step-0);
  font-weight: 600;
  color: var(--eme-white);
}
.nc__go {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  min-block-size: 2.25rem;
  padding-block: 0.25rem;
  font-size: var(--eme-step--1);
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--net-soft);
  border-block-end: 1px solid rgb(255 255 255 / 0.25);
  transition:
    color var(--eme-fast) var(--eme-ease),
    border-color var(--eme-fast) var(--eme-ease);
}
html[lang="ar"] .nc__go {
  letter-spacing: 0;
}
.nc__go svg {
  transition: transform var(--eme-med) var(--eme-ease-out);
}
.nc__go:hover {
  color: var(--eme-white);
  border-color: var(--eme-red);
}
.nc__go:hover svg {
  transform: translate(2px, -2px);
}
html[dir="rtl"] .nc__go svg {
  transform: scaleX(-1);
}
html[dir="rtl"] .nc__go:hover svg {
  transform: scaleX(-1) translate(2px, -2px);
}
.nc a:focus-visible {
  outline: 2px solid var(--eme-red);
  outline-offset: 3px;
}

/* Under the cards (Contact): the hours and the offices that are not factories. */
.network__foot {
  display: flex;
  flex-wrap: wrap;
  gap: var(--eme-space-3) clamp(1.5rem, 4vw, 3.5rem);
  margin-block-start: var(--eme-space-6);
  font-size: var(--eme-step-0);
  color: var(--net-soft);
}
.network__foot p {
  margin: 0;
}
.network__foot span {
  display: block;
  font-size: var(--eme-step--1);
  color: var(--net-muted);
}

/* ------------------------------------------------------------- breakpoints */

/* Phones: the factories stand close, so each pin names its country only; the
   card below it carries the city. */
@media (max-width: 35.99rem) {
  .network__city {
    display: none;
  }
  .network__country-name {
    color: var(--eme-white);
    font-weight: 600;
  }
}

@media (min-width: 36rem) {
  .network__map {
    --z: 1.5;
    --px: 54%;
    --py: 43%;
    aspect-ratio: 2;
  }
}

/* Phones on their side: a wide, short band, so the map never outgrows the
   screen it is seen on. */
@media (orientation: landscape) and (max-height: 32rem) and (max-width: 61.99rem) {
  .network__map {
    --z: 1.25;
    --px: 55%;
    --py: 39%;
    aspect-ratio: 2.3;
  }
}

/* Tablets: one card per row, as wide as the page. Who and where on one side,
   the figures and the ways in on the other. */
@media (min-width: 44rem) and (max-width: 61.99rem) {
  .nc {
    display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(0, 1.15fr);
    grid-template-areas:
      "id facts"
      "place facts"
      "place actions";
    align-items: start;
    column-gap: clamp(2rem, 5vw, 3.5rem);
    row-gap: var(--eme-space-4);
  }
  .nc__id {
    grid-area: id;
  }
  .nc__place,
  .nc__address {
    grid-area: place;
  }
  .nc__facts,
  .nc__reach {
    grid-area: facts;
    border-block-start: 0;
    padding-block-start: 0;
  }
  .nc__actions {
    grid-area: actions;
  }
}

@media (min-width: 62rem) {
  /* The band's height is set rather than its ratio, so capping it on a wide
     monitor never narrows it. */
  .network__map {
    --z: 1.4;
    --px: 56%;
    --py: 38.5%;
    aspect-ratio: auto;
    block-size: min(calc(100vw / 2.3), 46rem);
    margin-block-start: clamp(-4rem, -3.3vw, -2rem);
  }
  .network__list {
    grid-template-columns: repeat(3, minmax(0, 1fr));
    margin-block-start: clamp(-5.5rem, -5.5vw, -3rem);
  }
  /* The three cards share their rows, so a name, an address or a line of
     figures that runs longer in one card keeps the others level with it. */
  .nc {
    grid-row: span 4;
    grid-template-rows: subgrid;
  }
  .nc__actions {
    align-self: start;
  }
}

/* Three cards across, each wide enough (about 400px) for all three figures on
   one line. The market takes what is left and wraps inside its own column, so
   a long one (the Maghreb & Levant) costs a line, not a row. A card's own
   width cannot be queried here: a size container would switch off the
   subgrid that keeps the three cards level. */
@media (min-width: 86rem) {
  .nc__facts {
    grid-template-columns: auto auto minmax(0, 1fr);
  }
  .nc__market {
    grid-column: auto;
  }
}

/* Wide monitors: the band stops growing taller, so the map zooms out a step
   to keep all three countries inside it. */
@media (min-width: 100rem) {
  .network__map {
    --z: 1.25;
  }
}

/* ------------------------------------------------------------------ motion
   The map draws itself once: countries, then the routes out of head office,
   then the pins. Contact opens on it, so it plays on load; About's plays when
   the map scrolls into view (site.js arms it only when it starts below the
   fold, so a reader who lands on it sees it finished). */
@keyframes net-fade {
  from {
    opacity: 0;
  }
}
@keyframes net-draw {
  from {
    stroke-dashoffset: 1;
  }
  to {
    stroke-dashoffset: 0;
  }
}
@keyframes net-pin {
  from {
    opacity: 0;
    transform: translateY(8px);
  }
}
@keyframes net-ping {
  from {
    transform: scale(1);
    opacity: 0.9;
  }
  to {
    transform: scale(4);
    opacity: 0;
  }
}
@keyframes net-flow {
  0% {
    stroke-dashoffset: 0.07;
    opacity: 0;
  }
  10% {
    opacity: 0.9;
  }
  85% {
    opacity: 0.9;
  }
  100% {
    stroke-dashoffset: -0.93;
    opacity: 0;
  }
}
@keyframes net-rise {
  from {
    opacity: 0;
    transform: translateY(1.25rem);
  }
}

.network--hero .network__country,
.network.is-armed .network__map.is-in .network__country {
  animation: net-fade 900ms var(--eme-ease) 250ms both;
}
.network--hero .network__route,
.network.is-armed .network__map.is-in .network__route {
  animation: net-draw 1500ms var(--eme-ease-out) 800ms both;
}
.network--hero .network__route ~ .network__route,
.network.is-armed .network__map.is-in .network__route ~ .network__route {
  animation-delay: 1000ms;
}
.network--hero .network__pin,
.network.is-armed .network__map.is-in .network__pin {
  animation: net-pin 700ms var(--eme-ease-out) both;
  animation-delay: calc(550ms + var(--n, 0) * 150ms);
}
/* Armed and not yet in view: the finished state waits, and nothing travels
   routes that are not drawn yet. */
.network.is-armed .network__map:not(.is-in) .network__country,
.network.is-armed .network__map:not(.is-in) .network__pin {
  opacity: 0;
}
.network.is-armed .network__map:not(.is-in) .network__route {
  stroke-dashoffset: 1;
}
.network.is-armed .network__map:not(.is-in) .network__flow {
  animation: none;
}
/* The cards come in with the map, as the pins land, rather than on their own
   cue: docked into the map's foot, they would otherwise leave it empty until
   the reader scrolled a little further. */
.network.is-armed .network__map:not(.is-in) ~ .network__dock .nc {
  opacity: 0;
}
.network--hero .nc,
.network.is-armed .network__map.is-in ~ .network__dock .nc {
  animation: net-rise 800ms var(--eme-ease-out) both;
  animation-delay: calc(700ms + var(--i, 0) * 110ms);
}

@media (prefers-reduced-motion: reduce) {
  .network *,
  .network *::before,
  .network *::after {
    animation: none !important;
    transition-duration: 0.01ms !important;
  }
  .network.is-armed .network__map:not(.is-in) .network__country,
  .network.is-armed .network__map:not(.is-in) .network__pin,
  .network.is-armed .network__map:not(.is-in) ~ .network__dock .nc {
    opacity: 1;
  }
  .network__route {
    stroke-dashoffset: 0 !important;
  }
  .network__flow {
    display: none;
  }
}
