/* ==========================================================================
   DMG — site layer

   Chrome (nav, footer) and the content blocks that src/views/blocks/*.ejs
   render. Component primitives live in components.css.
   ========================================================================== */

/* --------------------------------------------------------------------------
   Page shell
   -------------------------------------------------------------------------- */

/* The panel's height, declared at the root so content elsewhere in the tree
   can reserve space for it — a value living only on .mast resolves to nothing
   for its siblings, and any calc() using it is dropped silently.
   .mast redeclares it locally for its own box, including when it condenses. */
:root { --mast-h: 108px; }

html { scroll-behavior: smooth; }
body { min-height: 100vh; display: flex; flex-direction: column; }
/* The panel is out of flow now. A page that opens on a full-bleed hero wants
   it overlapping — that is the point of the notch — and anything else needs
   the space reserving. */
.site-main { flex: 1; }
.site-main:not(:has(> .video-bg:first-child)) { padding-top: var(--mast-h); }

/* Hero copy clears the panel it now sits beneath. */
.video-bg .page-hero__inner { padding-top: calc(var(--space-20) + var(--mast-h)); }
.video-bg .hero__grid { padding-top: calc(var(--space-16) + var(--mast-h)); }

/* Skip link — the nav is sticky, so it must clear it. */
.skip-link {
  position: absolute;
  left: var(--space-6);
  top: -100px;
  z-index: 100;
  padding: var(--space-3) var(--space-5);
  background: var(--navy-900);
  color: var(--white);
  border-radius: var(--radius-control);
  font: var(--type-label);
  letter-spacing: var(--ls-caps);
  text-transform: uppercase;
  transition: top var(--dur-fast) var(--ease-out);
}
.skip-link:focus { top: var(--space-4); color: var(--white); }

/* --------------------------------------------------------------------------
   Masthead — an instrument panel, not a header bar

   The design system's nav is a glass strip with wide-tracked caps and a cyan
   underline: correct, and indistinguishable from every other premium B2B
   header. This replaces it outright.

   The idea comes from the company's own product — precision instruments. The
   wordmark occupies a bay behind a hairline, like a badge on a device. The
   navigation runs along a calibrated rail with a tick under every item, and a
   cyan needle slides between them to indicate the reading. Labels are set in
   sentence case at 14px with tight tracking, which is the clearest break from
   the tracked-caps convention the rest of the category uses.

   The needle is the single bold element. Everything else — the bay, the rail,
   the ticks, the type — is held quiet so it can be.
   -------------------------------------------------------------------------- */

.mast {
  --mast-h: 108px;
  /* The window the logo sits in. JS measures the real bay and rewrites these;
     the values here are a close standing-in so the notch exists before script
     runs and on any page where it never does. */
  --win-l: 32px;
  --win-r: 191px;
  --win-t: 16px;
  /* Fixed, not sticky. A sticky header occupies its own layout box, so at
     rest the only thing behind the notch is the document's own white ground —
     which is exactly the white the notch was cut to get rid of. Fixed lifts
     the panel off the page so the hero sits underneath it from the first
     pixel, and the window shows the page rather than the gap above it. */
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  z-index: 40;
  background: none;
}

/* The dark panel, with the logo bay cut out of it. The notch opens downward
   from --win-t, so the gradient stays unbroken across the full width above the
   logo and the page itself shows through beneath — no plate, no fill, just an
   absence. Whatever is scrolling past is what you see behind the mark. */
.mast__panel {
  position: absolute;
  inset: 0;
  z-index: 0;
  background: var(--panel-bg);
  backdrop-filter: saturate(165%) blur(20px);
  transition: background var(--dur-base) var(--ease-standard);
  clip-path: polygon(
    0 0,
    100% 0,
    100% 100%,
    var(--win-r) 100%,
    var(--win-r) var(--win-t),
    var(--win-l) var(--win-t),
    var(--win-l) 100%,
    0 100%
  );
}

/* Past the first screen the panel condenses — shorter, darker — so it reads
   as an instrument settling into a working state.

   The fill is declared here rather than on .mast__panel because the bay that
   fills the notch must paint the identical thing; two literal copies drifted
   the moment this condensed state changed one of them. */
.mast { --panel-bg: linear-gradient(180deg, rgba(3, 11, 22, .94) 0%, rgba(6, 22, 46, .86) 62%, rgba(7, 27, 58, .80) 100%); }
.mast.is-compact {
  --mast-h: 94px;
  --win-t: 13px;
  --panel-bg: linear-gradient(180deg, rgba(2, 8, 17, .96) 0%, rgba(4, 16, 31, .92) 100%);
}

.mast__inner {
  position: relative;
  z-index: 1;
  max-width: var(--container-wide);
  margin-inline: auto;
  padding-inline: var(--space-8);
  height: var(--mast-h);
  display: flex;
  align-items: stretch;
  gap: var(--space-8);
  transition: height var(--dur-base) var(--ease-standard);
}

/* --- the wordmark bay -----------------------------------------------------
   No background of its own. It only reserves the space that the panel's notch
   is cut to match, and centres the mark inside it.
   ------------------------------------------------------------------------- */
/* --- what sits in the notch ----------------------------------------------
   Both layers are the whole masthead box clipped to exactly the bay — the
   complement of the panel's notch — so they register with the hole without
   restating its geometry. Over a dark bed the header's own gradient continues
   across the bay and the knockout mark reads on it; over a light bed the bay
   turns white, which both suits the colour mark and stops black page text
   from scrolling through it. */
.mast__bay {
  position: absolute;
  inset: 0;
  z-index: 0;
  clip-path: polygon(
    var(--win-l) var(--win-t),
    var(--win-r) var(--win-t),
    var(--win-r) 100%,
    var(--win-l) 100%);
  transition: opacity var(--dur-slow, 420ms) var(--ease-standard, ease);
}
.mast__bay--head {
  background: var(--panel-bg);
  backdrop-filter: saturate(165%) blur(20px);
}
/* --bay-fill is written by the scroll reader from the computed background of
   the section actually passing under the bay, so the mark sits on that
   section's own surface instead of on a white plate that matches only one of
   the three light tones. */
.mast__bay--fill {
  background: var(--bay-fill, var(--surface-page, #fff));
  opacity: 0;
  transition: opacity var(--dur-slow, 420ms) var(--ease-standard, ease),
              background-color var(--dur-slow, 420ms) var(--ease-standard, ease);
}

.mast.is-over-light .mast__bay--head { opacity: 0; }
.mast.is-over-light .mast__bay--fill { opacity: 1; }

.mast__badge {
  position: relative;
  z-index: 1;
  align-self: flex-start;
  display: flex;
  align-items: center;
  justify-content: center;
  flex: 0 0 auto;
  margin-top: var(--win-t);
  height: calc(var(--mast-h) - var(--win-t));
  /* The gap between the mark and the edge of the hole. The notch is cut to
     this box, so this value alone sets how much room the logo gets.
     A literal, not a token: the scale jumps 24 -> 32 and neither is the 30
     asked for. */
  padding-inline: 30px;
  transition: height var(--dur-base) var(--ease-standard),
              margin-top var(--dur-base) var(--ease-standard);
}
.mast__logo {
  display: block;
  height: 52px;
  width: auto;
  transition: height var(--dur-base) var(--ease-standard);
}
.mast.is-compact .mast__logo { height: 48px; }

/* The two marks are stacked, not swapped: the knockout is lifted out of flow
   so the colour mark alone sets the bay's width, and they crossfade. Dark bed
   is the resting state — that is what the top of every page is. */
.mast__logo { transition: height var(--dur-base) var(--ease-standard), opacity var(--dur-slow, 420ms) var(--ease-standard, ease); }
.mast__logo--colour { opacity: 0; }
.mast__logo--white {
  position: absolute;
  left: 50%;
  top: 50%;
  transform: translate(-50%, -50%);
  opacity: 1;
}
.mast.is-over-light .mast__logo--colour { opacity: 1; }
.mast.is-over-light .mast__logo--white  { opacity: 0; }

@media (prefers-reduced-motion: reduce) {
  .mast__bay, .mast__logo { transition: none; }
}


/* --- the calibrated rail -------------------------------------------------- */
.mast__rail {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  height: 1px;
  background: linear-gradient(90deg,
    rgba(255, 255, 255, .02) 0%,
    rgba(255, 255, 255, .12) 18%,
    rgba(255, 255, 255, .12) 82%,
    rgba(255, 255, 255, .02) 100%);
}

.mast__nav {
  position: relative;
  margin-left: auto;
  display: flex;
  align-items: stretch;
}
.mast__list {
  display: flex;
  align-items: stretch;
  list-style: none;
  margin: 0;
  padding: 0;
}
.mast__item { display: flex; }

.mast__link {
  position: relative;
  display: flex;
  align-items: center;
  padding-inline: var(--space-5);
  font-family: var(--font-display);
  font-size: 17px;
  font-weight: var(--fw-semibold);
  letter-spacing: -.005em;
  white-space: nowrap;
  /* Each of the three custom properties is set per item in Navigation, and
     falls back to the theme colour when that item has none - so an untouched
     menu renders exactly as it always did. */
  color: var(--nav-colour, rgba(255, 255, 255, .74));
  text-decoration: none;
  transition: color var(--dur-fast) var(--ease-standard);
}
.mast__link:hover { color: var(--nav-colour-hover, var(--white)); }
.mast__link.is-active { color: var(--nav-colour-active, var(--white)); }

/* Scale marks. Every item carries one; the needle travels across them. */
.mast__tick {
  position: absolute;
  left: 50%;
  bottom: 0;
  width: 1px;
  height: 7px;
  background: rgba(255, 255, 255, .20);
  transition: height var(--dur-fast) var(--ease-out), background-color var(--dur-fast) var(--ease-standard);
}
.mast__link:hover .mast__tick { height: 12px; background: var(--cyan-400); }
.mast__link.is-active .mast__tick { background: var(--cyan-400); }

/* The needle. JS gives it a position and a width; this is only its look. */
.mast__needle {
  position: absolute;
  bottom: 0;
  left: 0;
  width: 0;
  height: 2px;
  border-radius: 2px;
  background: var(--gradient-signal);
  box-shadow: 0 0 16px 1px rgba(34, 193, 227, .55);
  opacity: 0;
  pointer-events: none;
  transform: translateX(0);
  transition:
    transform 620ms cubic-bezier(.17, .89, .32, 1.02),
    width 620ms cubic-bezier(.17, .89, .32, 1.02),
    opacity var(--dur-base) var(--ease-standard);
}
.js-mast .mast__needle.is-set { opacity: 1; }

/* No-JS fallback: the active item draws its own bar. Suppressed the moment
   the needle takes over, so the two can never both be visible. */
.mast__link.is-active::after {
  content: "";
  position: absolute;
  left: var(--space-5);
  right: var(--space-5);
  bottom: 0;
  height: 2px;
  border-radius: 2px;
  background: var(--gradient-signal);
}
.js-mast .mast__link.is-active::after { display: none; }

/* --- actions -------------------------------------------------------------- */
.mast__actions {
  display: flex;
  align-items: center;
  gap: var(--space-4);
  padding-left: var(--space-8);
  border-left: 1px solid rgba(255, 255, 255, .09);
  flex: 0 0 auto;
}

/* The one filled control in the header: a cyan hairline that floods on hover,
   the arrow leading and the fill following. */
.mast__cta {
  position: relative;
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  height: 46px;
  padding-inline: var(--space-5);
  border: 1px solid rgba(127, 220, 242, .38);
  border-radius: var(--radius-control);
  font-family: var(--font-display);
  font-size: 17px;
  font-weight: var(--fw-medium);
  letter-spacing: .02em;
  color: var(--cyan-300);
  text-decoration: none;
  overflow: hidden;
  transition: color var(--dur-base) var(--ease-standard), border-color var(--dur-base) var(--ease-standard);
}
.mast__cta > * { position: relative; z-index: 1; }
.mast__cta::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 0;
  background: var(--gradient-signal);
  transform: scaleX(0);
  transform-origin: left center;
  transition: transform var(--dur-base) var(--ease-out);
}
.mast__cta:hover { color: var(--navy-950); border-color: transparent; }
.mast__cta:hover::before { transform: scaleX(1); }
.mast__cta .dmg-icon { transition: transform var(--dur-fast) var(--ease-out); }
.mast__cta:hover .dmg-icon { transform: translateX(3px); }

/* --- burger --------------------------------------------------------------- */
.mast__toggle {
  display: none;
  width: 44px;
  height: 44px;
  place-items: center;
  background: none;
  border: 1px solid rgba(255, 255, 255, .14);
  border-radius: var(--radius-control);
  cursor: pointer;
  transition: var(--transition-control);
}
.mast__toggle:hover { border-color: var(--border-accent); }

/* Two rules that become an X. */
.mast__burger, .mast__burger::before, .mast__burger::after {
  display: block;
  width: 18px;
  height: 1.5px;
  background: var(--white);
  transition: transform var(--dur-base) var(--ease-out);
}
.mast__burger { position: relative; background: transparent; }
.mast__burger::before, .mast__burger::after { content: ""; position: absolute; left: 0; }
.mast__burger::before { top: -5px; }
.mast__burger::after { top: 5px; }
.mast.is-open .mast__burger::before { transform: translateY(5px) rotate(45deg); }
.mast.is-open .mast__burger::after { transform: translateY(-5px) rotate(-45deg); }

/* --- drawer --------------------------------------------------------------- */
.mast__drawer {
  position: fixed;
  inset: var(--mast-h) 0 0 0;
  z-index: 39;
  display: none;
  flex-direction: column;
  justify-content: center;
  gap: var(--space-8);
  padding: var(--space-10) var(--gutter) var(--space-20);
  background: linear-gradient(180deg, rgba(4, 16, 31, .99), rgba(7, 27, 58, .99));
  backdrop-filter: blur(24px);
  overflow-y: auto;
}
.mast.is-open .mast__drawer { display: flex; }

.mast__drawer ul { list-style: none; margin: 0; padding: 0; display: grid; gap: var(--space-1); }
.mast__drawer li {
  opacity: 0;
  animation: mast-step-in 520ms var(--ease-out) forwards;
  animation-delay: calc(var(--i) * 55ms + 60ms);
}
/* Scoped to the list. A bare `.mast__drawer a` also matched the CTA below it,
   which then inherited the 40px link size and the pale link colour instead of
   its own navy-on-cyan — the button read as another menu item. */
.mast__drawer ul a {
  display: flex;
  align-items: center;
  gap: var(--space-5);
  padding-block: var(--space-4);
  border-bottom: 1px solid rgba(255, 255, 255, .07);
  font-family: var(--font-display);
  font-size: clamp(28px, 7vw, 40px);
  font-weight: var(--fw-light);
  letter-spacing: var(--ls-display);
  color: rgba(255, 255, 255, .78);
  text-decoration: none;
}
.mast__drawer ul a:hover, .mast__drawer ul a.is-active { color: var(--white); }
.mast__drawer-index {
  width: 8px;
  height: 8px;
  flex: 0 0 auto;
  border-radius: 50%;
  border: 1px solid rgba(127, 220, 242, .5);
  transition: var(--transition-control);
}
.mast__drawer ul a.is-active .mast__drawer-index { background: var(--cyan-400); border-color: var(--cyan-400); }

.mast__drawer-cta {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-3);
  height: var(--control-h-lg);
  padding-inline: var(--space-8);
  background: var(--gradient-signal);
  border-radius: var(--radius-control);
  font-family: var(--font-display);
  font-size: var(--fs-body);
  font-weight: var(--fw-medium);
  letter-spacing: .04em;
  text-transform: uppercase;
  color: var(--navy-950);
  text-decoration: none;
  opacity: 0;
  animation: mast-step-in 520ms var(--ease-out) forwards;
  animation-delay: calc(var(--i) * 55ms + 60ms);
}
.mast__drawer-cta:hover { color: var(--navy-950); }

@keyframes mast-step-in { from { opacity: 0; transform: translateY(18px); } to { opacity: 1; transform: none; } }

@media (prefers-reduced-motion: reduce) {
  .mast__needle { transition: none; }
  .mast__drawer li, .mast__drawer-cta { animation: none; opacity: 1; }
}

/* --------------------------------------------------------------------------
   Footer
   -------------------------------------------------------------------------- */

.site-footer { position: relative; background: var(--navy-950); color: var(--text-inverse-muted); }
.site-footer__inner {
  max-width: var(--container-max);
  margin-inline: auto;
  padding: var(--space-20) var(--gutter) var(--space-10);
  display: grid;
  /* The brand track is a fixed size on purpose: repeat(auto-fit, ...) is
     invalid alongside a flexible (fr) track, and a browser drops the whole
     declaration when it sees one — which is what collapsed this footer into a
     single stacked column. Link columns stay auto-fit so adding or removing a
     column in Navigation still lays out correctly. */
  grid-template-columns: minmax(220px, 300px) repeat(auto-fit, minmax(150px, 1fr));
  gap: var(--space-12);
  align-items: start;
}
.site-footer__brand { display: grid; gap: var(--space-5); align-content: start; }
.site-footer__brand img { height: 60px; width: auto; }
.site-footer__social { display: flex; gap: var(--space-3); }
.site-footer__social a {
  display: grid;
  place-items: center;
  width: 36px; height: 36px;
  border: 1px solid var(--border-inverse);
  border-radius: var(--radius-control);
  color: var(--white);
  transition: var(--transition-control);
}
.site-footer__social a:hover { border-color: var(--border-accent); color: var(--cyan-300); }
/* A social account whose URL has not been supplied yet: shown, but not a link,
   so the row can never ship as three dead buttons. */
.site-footer__social .is-unset {
  display: grid;
  place-items: center;
  width: 36px;
  height: 36px;
  border: 1px dashed var(--border-inverse);
  border-radius: var(--radius-control);
  color: var(--text-inverse-muted);
  opacity: .6;
}

.site-footer__col { display: grid; gap: var(--space-4); align-content: start; }
.site-footer__col h2 {
  font: var(--type-caps);
  letter-spacing: var(--ls-caps);
  text-transform: uppercase;
  color: var(--white);
}
.site-footer__col ul { list-style: none; margin: 0; padding: 0; display: grid; gap: var(--space-3); }
.site-footer__col a,
.site-footer__col span { font-family: var(--font-sans); font-size: var(--fs-sm); color: var(--text-inverse-muted); }
/* Same three properties as the masthead, same fallbacks. Split from the rule
   above so the contact column's plain spans keep the muted colour. */
.site-footer__col a { color: var(--nav-colour, var(--text-inverse-muted)); }
.site-footer__col a:hover { color: var(--nav-colour-hover, var(--cyan-300)); }
.site-footer__col a.is-active { color: var(--nav-colour-active, var(--cyan-300)); }

.site-footer__legal { position: relative; border-top: 1px solid var(--border-inverse); }
.site-footer__legal > div {
  max-width: var(--container-max);
  margin-inline: auto;
  padding: var(--space-5) var(--gutter);
  display: flex;
  justify-content: space-between;
  gap: var(--space-6);
  font-family: var(--font-display);
  font-size: var(--fs-xs);
  letter-spacing: .08em;
  color: var(--n-500);
}
.site-footer__legal a { color: var(--n-500); }
.site-footer__legal a:hover { color: var(--cyan-300); }
.site-footer__legal-right { display: flex; align-items: center; flex-wrap: wrap; gap: var(--space-6); }
.site-footer__credit a { color: var(--n-400); border-bottom: 1px solid transparent; }
.site-footer__credit a:hover { color: var(--cyan-300); border-bottom-color: currentColor; }

/* --------------------------------------------------------------------------
   Block: hero_video — the home hero
   -------------------------------------------------------------------------- */

.hero__grid {
  max-width: var(--container-wide);
  margin-inline: auto;
  padding: var(--space-24) var(--space-8) var(--space-20);
  display: grid;
  grid-template-columns: 1.05fr .95fr;
  gap: var(--space-16);
  align-items: center;
}
.hero__copy { display: grid; gap: var(--space-8); }
.hero__rule { display: block; width: 56px; height: 2px; border-radius: 2px; background: var(--cyan-400); }
.hero__title {
  font-family: var(--font-display);
  font-weight: var(--fw-light);
  font-size: var(--fs-display-1);
  line-height: var(--lh-tight);
  letter-spacing: var(--ls-display);
  color: var(--white);
  max-width: 16ch;
}
.hero__lead { font: var(--type-lead); color: var(--text-inverse-muted); max-width: 52ch; }
.hero__actions { display: flex; flex-wrap: wrap; gap: var(--space-4); }

.hero__aside {
  position: relative;
  min-height: 440px;
  display: grid;
  align-content: end;
  justify-items: end;
}
.hero__ring {
  position: absolute;
  top: 50%;
  border-radius: 50%;
  border: 1px solid rgba(127, 220, 242, .20);
  pointer-events: none;
}
.hero__ring--lg { right: 40px; width: 300px; height: 300px; margin-top: -150px; }
.hero__ring--sm { right: 110px; width: 160px; height: 160px; margin-top: -80px; border-color: rgba(127, 220, 242, .28); animation-delay: 1.4s; }

/* --------------------------------------------------------------------------
   Block: page_hero — interior pages
   -------------------------------------------------------------------------- */

.page-hero__inner {
  max-width: var(--container-max);
  margin-inline: auto;
  padding: var(--space-20) var(--gutter);
}

/* --------------------------------------------------------------------------
   Block: stat_band
   -------------------------------------------------------------------------- */

.stat-band { position: relative; z-index: 2; background: var(--navy-950); }
.stat-band__rule { position: relative; z-index: 2; height: 1px; background: var(--border-inverse); }
.stat-band__grid {
  max-width: var(--container-wide);
  margin-inline: auto;
  padding: var(--space-10) var(--space-8);
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: var(--space-10);
}

/* --------------------------------------------------------------------------
   Block: triptych — the D M G letterforms
   -------------------------------------------------------------------------- */

.triptych { display: grid; grid-template-columns: repeat(3, 1fr); gap: var(--space-10); }
.triptych__item { display: grid; gap: var(--space-4); align-content: start; }
.triptych__letter {
  font-family: var(--font-display);
  font-size: 64px;
  font-weight: 300;
  line-height: 1;
  background: var(--gradient-logo);
  -webkit-background-clip: text;
  background-clip: text;
  -webkit-text-fill-color: transparent;
  color: transparent;
}
.triptych__title { font: var(--type-h3); }
/* One colour each. Deep navy to bright cyan across the three reads as a
   progression rather than three unrelated highlights, and each still holds
   its own weight on the light bed this section sits on. */
.triptych__item:nth-child(1) .triptych__title { color: var(--navy-700); }
.triptych__item:nth-child(2) .triptych__title { color: var(--blue-500); }
.triptych__item:nth-child(3) .triptych__title { color: var(--cyan-600); }
.section--navy .triptych__item:nth-child(1) .triptych__title,
.section--deep .triptych__item:nth-child(1) .triptych__title { color: var(--blue-300); }
.section--navy .triptych__item:nth-child(2) .triptych__title,
.section--deep .triptych__item:nth-child(2) .triptych__title { color: var(--blue-400); }
.section--navy .triptych__item:nth-child(3) .triptych__title,
.section--deep .triptych__item:nth-child(3) .triptych__title { color: var(--cyan-400); }
.triptych__body { font: var(--type-body); color: var(--text-muted); }

/* --------------------------------------------------------------------------
   Block: category_grid / category_showcase
   -------------------------------------------------------------------------- */

/* Column counts come from the section's `columns` setting as data-cols, not an
   inline style — an inline grid-template-columns would outrank every media
   query in the responsive layer below and silently break small screens. */
.category-grid,
.feature-grid,
.partner-grid,
.stat-band__grid,
.auto-cols { display: grid; }

.category-grid[data-cols="1"], .feature-grid[data-cols="1"],
.partner-grid[data-cols="1"], .stat-band__grid[data-cols="1"],
.auto-cols[data-cols="1"] { grid-template-columns: 1fr; }
.category-grid[data-cols="2"], .feature-grid[data-cols="2"],
.partner-grid[data-cols="2"], .stat-band__grid[data-cols="2"],
.auto-cols[data-cols="2"] { grid-template-columns: repeat(2, 1fr); }
.category-grid[data-cols="3"], .feature-grid[data-cols="3"],
.partner-grid[data-cols="3"], .stat-band__grid[data-cols="3"],
.auto-cols[data-cols="3"] { grid-template-columns: repeat(3, 1fr); }
.category-grid[data-cols="4"], .feature-grid[data-cols="4"],
.partner-grid[data-cols="4"], .stat-band__grid[data-cols="4"],
.auto-cols[data-cols="4"] { grid-template-columns: repeat(4, 1fr); }
.category-grid[data-cols="5"], .feature-grid[data-cols="5"],
.partner-grid[data-cols="5"], .stat-band__grid[data-cols="5"],
.auto-cols[data-cols="5"] { grid-template-columns: repeat(5, 1fr); }

.category-grid { grid-template-columns: repeat(4, 1fr); gap: var(--space-6); }
/* The reveal lives on this wrapper so the card inside keeps its hover lift —
   a running animation outranks a plain transform declaration, so the two
   cannot share an element. */
.category-cell { display: flex; }
.category-cell > .category-card { flex: 1; }
.category-grid--3 { grid-template-columns: repeat(3, 1fr); }
.filter-row { display: flex; flex-wrap: wrap; gap: var(--space-3); margin-bottom: var(--space-10); }
.category-card.is-dimmed { opacity: .32; }

/* --------------------------------------------------------------------------
   Block: field_tags
   -------------------------------------------------------------------------- */

.field-tags {
  display: grid;
  grid-template-columns: .8fr 1.2fr;
  gap: var(--space-16);
  align-items: center;
}
.field-tags__list { display: flex; flex-wrap: wrap; gap: var(--space-3); }

/* --------------------------------------------------------------------------
   Block: cards / feature_grid / quote
   -------------------------------------------------------------------------- */

.feature-grid { display: grid; grid-template-columns: 1fr 1fr; gap: var(--space-4); }
.feature-grid__item {
  display: flex;
  gap: var(--space-3);
  align-items: flex-start;
  padding: var(--space-4);
  border: 1px solid var(--border-inverse);
  border-radius: var(--radius-md);
}
.feature-grid__item .dmg-icon { margin-top: 2px; color: var(--cyan-400); flex: 0 0 auto; }
.feature-grid__item span { font-family: var(--font-sans); font-size: var(--fs-sm); color: var(--text-inverse-muted); }

.quote-block { display: grid; grid-template-columns: 320px 1fr; gap: var(--space-16); align-items: center; }
/* Without a portrait the grid would leave a 320px hole and push the text off
   centre, so the solo case is a plain centred column instead. This has to sit
   after the rule above: same specificity, so order decides it. */
.quote-block--solo {
  display: block;
  max-width: 46rem;
  margin-inline: auto;
  text-align: center;
}
.quote-block--solo .stack { align-items: center; }
/* The quote glyph is a block-level svg, so text-align does not reach it. */
.quote-block--solo .stack > svg { margin-inline: auto; }
.quote-block--solo .quote-block__text { text-wrap: pretty; }
.quote-block__portrait {
  position: relative;
  aspect-ratio: 3 / 4;
  border-radius: var(--radius-media);
  overflow: hidden;
  border: 1px solid var(--border-inverse);
}
.quote-block__text {
  font-family: var(--font-display);
  font-weight: 300;
  font-size: var(--fs-h3);
  line-height: var(--lh-snug);
  color: var(--white);
}
.quote-block__attr {
  font: var(--type-label);
  letter-spacing: .18em;
  text-transform: uppercase;
  color: var(--cyan-300);
}

/* --------------------------------------------------------------------------
   Block: slider — the one carousel in the system
   -------------------------------------------------------------------------- */

.slider { position: relative; display: grid; gap: var(--space-8); }
.slider__viewport { overflow: hidden; }
.slider__track {
  display: flex;
  gap: var(--space-6);
  transition: transform var(--dur-slow) var(--ease-out);
  will-change: transform;
}
.slider__slide { flex: 0 0 auto; width: calc((100% - var(--space-6) * 2) / 3); }
.slider[data-per-view="2"] .slider__slide { width: calc((100% - var(--space-6)) / 2); }
.slider[data-per-view="1"] .slider__slide { width: 100%; }

.slide-card { display: grid; gap: 0; overflow: hidden; padding: 0; height: 100%; }
.slide-card__frame { position: relative; aspect-ratio: 16 / 10; overflow: hidden; background: var(--navy-900); }
.slide-card__frame::after { content: ""; position: absolute; inset: 0; background: var(--gradient-media-veil); }
.slide-card__img {
  position: absolute; inset: 0;
  width: 100%; height: 100%;
  object-fit: cover;
  filter: var(--image-treatment);
  opacity: 0;
  transition: opacity var(--dur-slow) var(--ease-out);
}
.slide-card__img.is-ready { opacity: 1; }
.slide-card__body { display: grid; gap: var(--space-3); padding: var(--card-pad-sm); align-content: start; }
.slide-card__title { font-family: var(--font-display); font-size: var(--fs-h4); font-weight: var(--fw-medium); color: var(--text-strong); }
.slide-card__text { font-family: var(--font-sans); font-size: var(--fs-sm); line-height: var(--lh-body); color: var(--text-muted); }

.slider__controls { display: flex; align-items: center; gap: var(--space-4); }
.slider__dots { display: flex; gap: var(--space-2); margin-left: auto; }
.slider__dot {
  width: 28px; height: 3px;
  border: 0; padding: 0;
  border-radius: 2px;
  background: var(--border-default);
  cursor: pointer;
  transition: var(--transition-control);
}
.slider__dot[aria-current="true"] { background: var(--gradient-signal); }
.slider__btn[disabled] { opacity: .4; cursor: not-allowed; }

/* --------------------------------------------------------------------------
   Block: tabs (Platform)
   -------------------------------------------------------------------------- */

.platform__grid {
  display: grid;
  grid-template-columns: 1.1fr .9fr;
  gap: var(--space-16);
  align-items: start;
}
.platform__aside { display: grid; gap: var(--space-6); }

/* --------------------------------------------------------------------------
   Block: partner_map
   -------------------------------------------------------------------------- */

.world-map { position: relative; }
.world-map__svg { width: 100%; height: auto; display: block; }
.world-map__country { fill: rgba(19, 69, 133, .34); stroke: rgba(127, 220, 242, .22); stroke-width: .5; }
.world-map__halo { fill: rgba(0, 163, 199, .18); }
.world-map__dot { fill: var(--cyan-400); transition: r var(--dur-fast) var(--ease-out); }
.world-map__hit { fill: transparent; pointer-events: all; cursor: default; }
.world-map__label {
  font-family: var(--font-display);
  font-weight: 600;
  font-size: 10px;
  letter-spacing: .14em;
  fill: var(--cyan-300);
  opacity: 0;
  transition: opacity var(--dur-fast) var(--ease-standard);
}
.world-map__label--always { opacity: 1; }
.world-map__label-bg { fill: rgba(4, 16, 31, .88); opacity: 0; transition: opacity var(--dur-fast) var(--ease-standard); }
.world-map__pin:hover .world-map__label,
.world-map__pin:hover .world-map__label-bg,
.world-map__pin.is-lit .world-map__label,
.world-map__pin.is-lit .world-map__label-bg { opacity: 1; }
.world-map__pin:hover .world-map__label,
.world-map__pin.is-lit .world-map__label { fill: var(--white); }
.world-map__pin:hover .world-map__dot,
.world-map__pin.is-lit .world-map__dot { r: 5; fill: var(--cyan-300); }
.world-map__hq text { font-family: var(--font-display); font-weight: 600; font-size: 10px; letter-spacing: .14em; fill: var(--white); }
.world-map__hint {
  position: absolute;
  right: 0; bottom: 0;
  font: var(--type-label);
  letter-spacing: var(--ls-caps);
  text-transform: uppercase;
  color: var(--n-500);
}

/* The ten countries read as the map's legend rather than a row of boxes: each
   card carries a cyan marker echoing the pin above it, and hovering either end
   lights the other (see mapTips in /js/dmg.js). Five across means the ten
   entries land as two full rows with no ragged tail. */
.partner-grid { display: grid; grid-template-columns: repeat(5, 1fr); gap: var(--space-4); }
/* Carries the reveal, so the card inside keeps its own hover transform. */
.partner-grid__cell { display: flex; }
.partner-grid__item {
  position: relative;
  flex: 1;
  display: grid;
  align-content: center;
  gap: 5px;
  padding: var(--space-4) var(--space-4) var(--space-4) 34px;
  border: 1px solid var(--border-inverse);
  border-radius: var(--radius-md);
  background: linear-gradient(180deg, rgba(255, 255, 255, .045), rgba(255, 255, 255, 0));
  transition: border-color var(--dur-base) var(--ease-standard),
              background var(--dur-base) var(--ease-standard),
              transform var(--dur-base) var(--ease-standard);
}
/* The marker, sized and coloured to match the map's pin dots. Centred against
   the card so it sits right whether or not the entry carries a note. */
.partner-grid__item::before {
  content: "";
  position: absolute;
  left: 15px;
  top: 50%;
  width: 7px;
  height: 7px;
  margin-top: -3.5px;
  border-radius: 50%;
  background: var(--cyan-500);
  box-shadow: 0 0 0 0 rgba(34, 193, 227, .5);
  transition: background var(--dur-base) var(--ease-standard),
              box-shadow var(--dur-base) var(--ease-standard);
}
.partner-grid__item:hover,
.partner-grid__item.is-lit {
  border-color: var(--cyan-500);
  background: linear-gradient(180deg, rgba(34, 193, 227, .16), rgba(34, 193, 227, .02));
  transform: translateY(-3px);
}
.partner-grid__item:hover::before,
.partner-grid__item.is-lit::before {
  background: var(--cyan-300);
  box-shadow: 0 0 0 5px rgba(34, 193, 227, .2);
}
.partner-grid__country { font-family: var(--font-display); font-size: var(--fs-sm); font-weight: 500; color: var(--white); }
.partner-grid__note {
  font-family: var(--font-sans);
  font-size: 13px;
  line-height: 1.45;
  color: var(--text-inverse-muted);
}
.partner-note { display: flex; align-items: center; gap: var(--space-6); flex-wrap: wrap; }
.partner-note span { font-family: var(--font-sans); font-size: var(--fs-sm); color: var(--text-inverse-muted); }

/* --------------------------------------------------------------------------
   Block: contact_split
   -------------------------------------------------------------------------- */

.contact__grid {
  display: grid;
  grid-template-columns: .85fr 1.15fr;
  gap: var(--space-16);
  align-items: start;
}
.contact-list { display: grid; gap: var(--space-4); }
.contact-list__row { display: flex; gap: var(--space-3); align-items: center; }
.contact-list__row .dmg-icon { color: var(--cyan-600); flex: 0 0 auto; }
.contact-list__row a,
.contact-list__row span { font: var(--type-body); color: var(--text-body); }
.contact-list__row a:hover { color: var(--text-link-hover); }

.social-row { display: flex; gap: var(--space-3); }
.social-row a {
  display: grid;
  place-items: center;
  width: 40px; height: 40px;
  border: 1px solid var(--border-default);
  border-radius: var(--radius-control);
  color: var(--navy-800);
  transition: var(--transition-control);
}
.social-row a:hover { border-color: var(--border-accent); color: var(--cyan-600); }

.form-grid { display: grid; grid-template-columns: 1fr 1fr; gap: var(--space-5); }
.form-actions { display: flex; gap: var(--space-4); align-items: center; flex-wrap: wrap; }

/* --------------------------------------------------------------------------
   Block: cta_band
   -------------------------------------------------------------------------- */

.cta-band {
  display: grid;
  gap: var(--space-8);
  justify-items: start;
}
.cta-band__title {
  font-family: var(--font-display);
  font-weight: var(--fw-light);
  font-size: var(--fs-h2);
  line-height: var(--lh-snug);
  letter-spacing: var(--ls-display);
  color: var(--white);
  max-width: 46rem;
}

/* --------------------------------------------------------------------------
   Category detail page
   -------------------------------------------------------------------------- */

.category-detail__meta { display: flex; flex-wrap: wrap; gap: var(--space-2); }

/* Preview banner shown when an editor views an unpublished page. */
.preview-bar {
  position: sticky;
  top: var(--mast-h);
  z-index: 39;
  padding: var(--space-3) var(--gutter);
  background: var(--status-warning-soft);
  color: #6B4C05;
  font: var(--type-label);
  letter-spacing: var(--ls-caps);
  text-transform: uppercase;
  text-align: center;
}

/* --------------------------------------------------------------------------
   Responsive

   Nine bands. The design system kit was authored desktop-only at 1440 and
   states that "responsive breakpoints are not designed yet", so this layer is
   the whole of it — but every value below is still a token, ratio or treatment
   the system defines.

     >= 1920   wide desks: the container grows rather than the margins
     1600-1920 large desks
     1366-1600 the size the kit was drawn at — the reference
     1200-1366 laptops: container tightens, the nav rail closes up
     1024-1200 small laptops: four-up becomes three-up
      880-1024 tablets landscape: the rail gives way to the drawer
      767-880  tablets portrait: two-up
      460-767  large phones: one column
      320-460  small phones: one column, tighter everything

   Written mobile-last (max-width) so the desktop reference stays the base and
   each band only states what changes from the band above it.
   -------------------------------------------------------------------------- */

/* --- >= 1920 -------------------------------------------------------------- */
@media (min-width: 1920px) {
  :root {
    --container-max: 1440px;
    --container-wide: 1720px;
    --gutter: 32px;
    --section-y: var(--space-40);
    --section-y-tight: var(--space-24);
  }
  .hero__title { font-size: clamp(52px, 4.2vw, 80px); }
  .hero__grid { padding-block: var(--space-32) var(--space-24); }
  .hero__aside { min-height: 520px; }
  .hero__ring--lg { width: 360px; height: 360px; margin-top: -180px; }
  .hero__ring--sm { width: 200px; height: 200px; margin-top: -100px; }
}

/* --- 1600 - 1920 ---------------------------------------------------------- */
@media (min-width: 1600px) and (max-width: 1919.98px) {
  :root {
    --container-max: 1360px;
    --container-wide: 1560px;
    --section-y: var(--space-32);
  }
  .hero__aside { min-height: 480px; }
}

/* --- 1366 - 1600 : the reference. No overrides; the base is this band. ---- */

/* --- 1200 - 1366 ---------------------------------------------------------- */
@media (max-width: 1365.98px) {
  :root { --container-max: 1140px; }
  .mast__inner { padding-inline: var(--space-6); gap: var(--space-6); }
  .mast__link { padding-inline: var(--space-4); font-size: 17px; }
  .mast__actions { padding-left: var(--space-6); }
  .hero__grid { padding-inline: var(--space-6); gap: var(--space-12); }
  .stat-band__grid { padding-inline: var(--space-6); }
  .split, .platform__grid, .contact__grid, .field-tags { gap: var(--space-12); }
}

/* --- 1024 - 1200 ---------------------------------------------------------- */
@media (max-width: 1199.98px) {
  :root {
    --container-max: 960px;
    --section-y: var(--space-24);
    --section-y-tight: var(--space-16);
  }
  .mast__link { padding-inline: var(--space-3); font-size: 17px; }
  .mast__badge { padding-inline: 28px; }
  .mast__logo { height: 45px; }

  /* Four across stops being four across before the tiles get narrow. */
  .category-grid[data-cols="4"] { grid-template-columns: repeat(3, 1fr); }
  .partner-grid[data-cols="4"] { grid-template-columns: repeat(3, 1fr); }
  /* Five holds down to 1024: the tracks are still wide enough for "United
     Kingdom" there, and dropping to four would strand two on a third row. */

  .hero__grid { grid-template-columns: 1.15fr .85fr; gap: var(--space-10); }
  .hero__aside { min-height: 380px; }
}

/* --- 880 - 1024 : the rail gives way to the drawer ------------------------ */
@media (max-width: 1023.98px) {
  :root { --container-max: 100%; }

  .mast__nav { display: none; }
  .mast__cta { display: none; }
  .mast__toggle { display: grid; }
  /* The auto margin that pushed everything right lived on the rail, so hiding
     the rail left the burger sitting against the logo. */
  .mast__actions { margin-left: auto; border-left: 0; padding-left: 0; }

  .hero__grid { grid-template-columns: 1fr; padding-block: calc(var(--space-16) + var(--mast-h)) var(--space-16); }
  .hero__aside { min-height: 0; justify-items: start; }
  .hero__ring { display: none; }
  .video-bg .hero__grid { padding-top: calc(var(--space-12) + var(--mast-h)); }

  .grid--4, .category-grid, .category-grid[data-cols] { grid-template-columns: repeat(2, 1fr); }
  .grid--3, .triptych, .auto-cols[data-cols] { grid-template-columns: repeat(2, 1fr); }
  .stat-band__grid, .stat-band__grid[data-cols] { grid-template-columns: repeat(2, 1fr); gap: var(--space-8); }
  .partner-grid, .partner-grid[data-cols] { grid-template-columns: repeat(2, 1fr); }
  .feature-grid[data-cols] { grid-template-columns: repeat(2, 1fr); }

  .split, .split--text-wide, .split--media-wide, .split--aside,
  .platform__grid, .contact__grid, .field-tags, .quote-block {
    grid-template-columns: 1fr;
  }
  .split--reverse > :first-child { order: 0; }
  .quote-block__portrait { max-width: 280px; }

  .slider__slide { width: calc((100% - var(--space-6)) / 2); }
  .slider[data-per-view="1"] .slider__slide { width: 100%; }

  .row-between { flex-direction: column; align-items: flex-start; gap: var(--space-6); }

  .site-footer__inner { grid-template-columns: 1fr 1fr; gap: var(--space-10); }
}

/* --- 767 - 880 ------------------------------------------------------------ */
@media (max-width: 879.98px) {
  :root {
    --mast-h: 88px;
    --section-y: var(--space-20);
    --section-y-tight: var(--space-12);
  }
  .mast { --mast-h: 88px; --win-t: 12px; }
  .mast.is-compact { --mast-h: 84px; --win-t: 10px; }
  .mast__badge { padding-inline: 26px; }
  .mast__logo { height: 40px; }
  .mast.is-compact .mast__logo { height: 42px; }

  .triptych { grid-template-columns: 1fr; }
  .triptych__letter { font-size: 52px; }
  .quote-block__text { font-size: var(--fs-h4); }
}

/* --- 460 - 767 : one column ----------------------------------------------- */
@media (max-width: 766.98px) {
  :root {
    --gutter: 20px;
    --section-y: var(--space-16);
    --section-y-tight: var(--space-12);
    --card-pad: var(--space-6);
  }

  .hero__title { max-width: none; }
  .hero__actions { flex-direction: column; align-items: stretch; }
  .hero__actions .btn { width: 100%; }

  .grid--2, .grid--3, .grid--4, .triptych, .form-grid,
  .category-grid, .category-grid[data-cols],
  .feature-grid, .feature-grid[data-cols],
  .partner-grid, .partner-grid[data-cols],
  .auto-cols[data-cols] { grid-template-columns: 1fr; }
  .stat-band__grid, .stat-band__grid[data-cols] { grid-template-columns: repeat(2, 1fr); gap: var(--space-6); }

  .slider__slide, .slider[data-per-view="2"] .slider__slide { width: 100%; }

  .accordion__trigger { gap: var(--space-4); }
  .accordion__body { padding-left: 40px; }

  .site-footer__inner { grid-template-columns: 1fr; gap: var(--space-8); }
  .site-footer__legal > div { flex-direction: column; align-items: flex-start; gap: var(--space-2); }
  .site-footer__legal-right { flex-direction: column; align-items: flex-start; gap: var(--space-2); }

  .toast-stack { left: var(--space-4); right: var(--space-4); bottom: var(--space-4); }
  .toast { min-width: 0; max-width: none; }

  .contact-list__row { align-items: flex-start; }
  /* The map is 980 units wide by design; below this the country labels render
     at two or three pixels and read as specks. The pins keep the shape of the
     idea and the grid immediately underneath names every country in full, so
     nothing is lost by dropping the type. */
  .world-map__label, .world-map__hq text { display: none; }
}

/* --- 320 - 460 ------------------------------------------------------------ */
@media (max-width: 459.98px) {
  :root {
    --gutter: 16px;
    --mast-h: 78px;
    --section-y: var(--space-12);
    --section-y-tight: var(--space-10);
    --card-pad: var(--space-5);
    --card-pad-sm: var(--space-5);
  }
  .mast { --mast-h: 78px; --win-t: 9px; }
  .mast.is-compact { --mast-h: 76px; --win-t: 8px; }
  .mast__badge { padding-inline: 18px; }
  .mast__logo { height: 35px; }
  .mast.is-compact .mast__logo { height: 36px; }
  .mast__inner { padding-inline: var(--gutter); }

  .stat-band__grid, .stat-band__grid[data-cols] { grid-template-columns: 1fr; gap: var(--space-5); }
  .stat-band__grid { padding-inline: var(--gutter); }

  .hero__grid { padding-inline: var(--gutter); }
  .hero__title { font-size: 34px; }
  .section-heading__title { font-size: 28px; }
  .triptych__letter { font-size: 44px; }

  .form-actions { align-items: stretch; }
  .form-actions .btn { width: 100%; }

  .mast__drawer ul a { font-size: 24px; }
  .mast__drawer { gap: var(--space-6); padding-block: var(--space-8) var(--space-16); }

  .tabs { gap: var(--space-5); overflow-x: auto; }
  .tabs__tab { white-space: nowrap; }

  .accordion__body { padding-left: 0; }
  .accordion__trigger { gap: var(--space-3); }

  .quote-block__text { font-size: 18px; }
  .btn--lg { height: var(--control-h); padding-inline: var(--space-5); font-size: var(--fs-sm); }
}

/* --------------------------------------------------------------------------
   Print — drop the chrome, keep the content readable.
   -------------------------------------------------------------------------- */

@media print {
  .mast, .site-footer, .slider__controls, .media-panel__toggle,
  .skip-link, .preview-bar { display: none !important; }
  .section, .section--navy, .section--deep { background: #fff !important; color: #000 !important; padding-block: var(--space-8); }
  .video-bg__video, .video-bg__scrim { display: none !important; }
  .section-heading__title, .hero__title, .quote-block__text { color: #000 !important; }
}

/* The Platform hero stands on the map, one screen tall on every device.
   svh rather than vh: on a phone vh is the height with the browser chrome
   hidden, so a 100vh hero is taller than the screen until the user scrolls,
   and the copy starts below the fold. svh is the smallest viewport, which is
   the one that is always actually visible. */
.video-bg--map {
  min-height: 100vh;
  min-height: 100svh;
}
.page-hero__bed { position: absolute; inset: 0; z-index: 0; }
.page-hero__bed .citymap {
  width: 100%;
  height: 100%;
  border: 0;
  border-radius: 0;
  aspect-ratio: auto !important;
}
.page-hero__bed .citymap__svg { height: 100%; }
.page-hero__bed .citymap__credit { right: 14px; bottom: 10px; }

/* The scrim has to work harder over a map than over a video: the roads are
   fine light lines and the headline sits directly on them. */
.video-bg--map .video-bg__scrim {
  background: linear-gradient(100deg, rgba(4, 16, 31, .93) 0%, rgba(4, 16, 31, .78) 42%, rgba(4, 16, 31, .35) 100%);
}
.video-bg--map .video-bg__content { position: relative; z-index: 2; }

@media (max-width: 767px) {
  .video-bg--map .video-bg__scrim {
    background: linear-gradient(180deg, rgba(4, 16, 31, .9) 0%, rgba(4, 16, 31, .8) 55%, rgba(4, 16, 31, .92) 100%);
  }
}

/* --- world map tooltip -----------------------------------------------------
   One panel reused by every pin. Positioned in percentages of the figure so it
   tracks the pin through every viewport without the map's own scaling having
   to be recomputed in JS.
   ------------------------------------------------------------------------- */
.world-map { position: relative; }

.world-map__pin { cursor: pointer; }
.world-map__pin:focus { outline: none; }
.world-map__pin:focus-visible .world-map__dot { stroke: var(--cyan-300); stroke-width: 3; }
.world-map__hit { fill: transparent; }

.world-map__tip {
  position: absolute;
  z-index: 3;
  width: min(268px, 72vw);
  padding: 12px 14px;
  transform: translate(-50%, -100%);
  background: rgba(7, 27, 58, .97);
  border: 1px solid rgba(127, 220, 242, .34);
  border-radius: var(--radius-card);
  box-shadow: 0 18px 40px -18px rgba(4, 16, 31, .9);
  pointer-events: none;
  opacity: 0;
  transition: opacity var(--dur-fast) var(--ease-standard);
}
.world-map__tip[hidden] { display: none; }
.world-map__tip.is-on { opacity: 1; }

.world-map__tip-place {
  margin: 0 0 5px;
  font-family: var(--font-display);
  font-size: 15px;
  font-weight: 600;
  color: var(--white);
}
.world-map__tip-place span + span::before { content: " · "; color: var(--cyan-300); }
.world-map__tip-text {
  margin: 0;
  font-family: var(--font-sans);
  font-size: 13px;
  line-height: 1.45;
  color: var(--text-inverse-muted);
}

@media (max-width: 767px) {
  /* A 16px radius is a ~10px target once the map is scaled down to a phone.
     This is as large as the target can go before neighbouring European pins
     swallow each other entirely; the grid below is what guarantees every
     country is reachable by touch. */
  .world-map__hit { r: 30; }
  .world-map__tip { width: min(240px, 78vw); padding: 11px 13px; }
  .world-map__tip-text { font-size: 12.5px; }
}

/* --- pinch-zoom the world map on touch -------------------------------------
   touch-action has to be surrendered for the gesture to reach the handler at
   all: left alone, the browser pans the page instead and nothing happens.
   ------------------------------------------------------------------------- */
.world-map.is-zoomable .world-map__svg { touch-action: none; }
.world-map [data-map-scene] { transform-origin: 50% 50%; will-change: transform; }
.world-map.is-zoomed [data-map-scene] { cursor: grab; }

.world-map__zoomhint {
  position: absolute;
  left: 50%;
  bottom: 10px;
  transform: translateX(-50%);
  font-family: var(--font-mono);
  font-size: 11px;
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--text-inverse-muted);
  pointer-events: none;
  opacity: .75;
}
.world-map.is-zoomed .world-map__zoomhint { opacity: 0; }
@media (hover: hover) { .world-map__zoomhint { display: none; } }
