/* as201040.net. Ink ground, one lamp. See DESIGN.md. */

/* French sets a narrow no-break space (U+202F) before ; : ! ? and inside « ». Most faces
   lack that glyph and Chrome then draws half a word space, which reads as none: "Fine" holds
   only U+202F, 1/8 em wide, and every stack starts with it (shared/fonts, tools/fine.py). */
@font-face { font-family: "Fine"; src: url("fonts/fine.woff2") format("woff2"); unicode-range: U+202F; font-display: swap; }

@font-face {
  font-family: "Martian Mono";
  src: url("/assets/fonts/martian-mono-latin.woff2") format("woff2");
  font-weight: 100 800; font-stretch: 75% 112.5%; font-style: normal; font-display: swap;
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: "Martian Mono";
  src: url("/assets/fonts/martian-mono-latin-ext.woff2") format("woff2");
  font-weight: 100 800; font-stretch: 75% 112.5%; font-style: normal; font-display: swap;
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
  font-family: "Hanken Grotesk";
  src: url("/assets/fonts/hanken-grotesk-latin.woff2") format("woff2");
  font-weight: 100 900; font-style: normal; font-display: swap;
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: "Hanken Grotesk";
  src: url("/assets/fonts/hanken-grotesk-latin-ext.woff2") format("woff2");
  font-weight: 100 900; font-style: normal; font-display: swap;
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

/* Metric-matched fallbacks, measured against the real faces in Chrome: text keeps its place when the web fonts arrive.
   Martian Mono is matched at the 87.5% width the page uses for data. */
@font-face { font-family: "Hanken Grotesk fallback"; src: local("Arial"), local("ArialMT"); size-adjust: 98.3%; ascent-override: 101.7%; descent-override: 30.5%; line-gap-override: 0%; }
@font-face { font-family: "Martian Mono fallback"; src: local("Menlo"), local("Menlo-Regular"); size-adjust: 99.7%; ascent-override: 100.3%; descent-override: 20.1%; line-gap-override: 0%; }
@font-face { font-family: "Martian Mono fallback Consolas"; src: local("Consolas"); size-adjust: 109.1%; ascent-override: 91.7%; descent-override: 18.3%; line-gap-override: 0%; }

:root {
  --ink: oklch(26.1% 0.0317 220.0);
  --ink-deep: oklch(21.4% 0.0283 224.6);
  --rule: oklch(38.0% 0.0296 223.5);
  --graphite: oklch(75.9% 0.0198 222.2);
  --chalk: oklch(93.9% 0.0122 96.4);
  --lamp: oklch(86.7% 0.1293 80.8);
  --lamp-glow: oklch(86.7% 0.1293 80.8 / .42);
  --plate: oklch(21.4% 0.0283 224.6 / .82);
  --plate-strong: oklch(21.4% 0.0283 224.6 / .94);

  --sans: "Fine", "Hanken Grotesk", "Hanken Grotesk fallback", "Helvetica Neue", Arial, sans-serif;
  --mono: "Fine", "Martian Mono", "Martian Mono fallback", "Martian Mono fallback Consolas", ui-monospace, Menlo, Consolas, monospace;

  --pad: clamp(1.25rem, 4.2vw, 4.5rem);   /* 20 px on a phone, 24 px from 400 px (below), 4.5rem on a wide screen */
  --st: env(safe-area-inset-top, 0px);
  --sr: env(safe-area-inset-right, 0px);
  --sb: env(safe-area-inset-bottom, 0px);
  --sl: env(safe-area-inset-left, 0px);
  --col: min(38rem, 42vw);
  --gap: clamp(2rem, 4vw, 4rem);
  --top: 5.5rem;   /* the drawing field's top on a desktop, under the header's plates */
  --head: clamp(76px, 3.366rem + 5.678vw, 112px);   /* the header's height: 76 px on a phone, 112 px from 1024 px (BRIEF §0.4) */
  --bottom: 6.5rem;

  /* the frame: the field where the network drawing composes */
  --fl: calc(var(--pad) + var(--col) + var(--gap));
  --fw: calc(100vw - var(--fl) - var(--pad));
  --ft: var(--top);
  --fh: calc(100svh - var(--top) - var(--bottom));
  --ps: calc(min(var(--fw), var(--fh)) * .97);

  color-scheme: dark;
  background: var(--ink);
}
@media (min-width: 400px) { :root { --pad: clamp(1.5rem, 4.2vw, 4.5rem); } }

*, *::before, *::after { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; text-size-adjust: 100%; scroll-behavior: smooth; }
body {
  margin: 0;
  background: var(--ink);
  color: var(--chalk);
  font: 400 1.0625rem/1.55 var(--sans);
  font-kerning: normal;
  text-rendering: optimizeLegibility;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}
@media (prefers-reduced-motion: reduce) { html { scroll-behavior: auto; } }

/* between English and French, home and legal notice: a short cross-fade, the header stays put */
@view-transition { navigation: auto; }
::view-transition-group(root) { animation-duration: .2s; }
@media (prefers-reduced-motion: reduce) {
  @view-transition { navigation: none; }
  ::view-transition-group(*), ::view-transition-old(*), ::view-transition-new(*) { animation: none !important; }
}

h1, h2, .lede { text-wrap: balance; }
p, dd, li, figcaption { text-wrap: pretty; }
td, .v, .facts dd, .upstreams { font-variant-numeric: tabular-nums slashed-zero; }
body { font-optical-sizing: auto; }

a { color: inherit; text-decoration: underline; text-decoration-color: var(--rule); text-decoration-thickness: 1px; text-underline-offset: .22em; transition: text-decoration-color .2s, color .2s; }
a:hover { text-decoration-color: var(--lamp); }
:focus-visible { outline: 2px solid var(--lamp); outline-offset: 3px; border-radius: 2px; }

.sr { position: absolute !important; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); clip-path: inset(50%); white-space: nowrap; }
.skip { position: absolute; left: var(--pad); top: -4rem; z-index: 20; padding: .6rem .9rem; background: var(--chalk); color: var(--ink); font-weight: 600; text-decoration: none; }
.skip:focus { top: 1rem; }

.v { font-family: var(--mono); font-stretch: 87.5%; font-weight: 380; font-size: .9em; letter-spacing: -.005em; font-variant-numeric: slashed-zero; }
.dim { color: var(--graphite); }
:not(pre) > code { font-family: var(--mono); font-stretch: 87.5%; font-weight: 380; font-size: .88em; letter-spacing: -.005em; white-space: nowrap; }
.valid { color: var(--lamp); font-weight: 560; }

/* ---------- The world: the network, fixed behind everything ---------- */
.world { position: fixed; top: 0; left: 0; right: 0; height: 100vh; height: 100lvh; z-index: 0; overflow: hidden; }
.vis-canvas { position: absolute; inset: 0; width: 100%; height: 100%; display: block; opacity: 0; transition: opacity .5s ease-out; }
.vis-canvas.is-live { opacity: 1; }
/* the square where the drawing composes; the poster fills it until the canvas takes over */
.vis-box {
  position: absolute;
  left: calc(var(--fl) + (var(--fw) - var(--ps)) / 2);
  top: calc(var(--ft) + (var(--fh) - var(--ps)) / 2);
  width: var(--ps); height: var(--ps);
  pointer-events: none;
}
.vis-poster { position: absolute; inset: 0; width: 100%; height: 100%; max-width: none; transition: opacity .6s; }
.vis-poster.is-gone { opacity: 0; }
/* the names: placed on the poster by CSS, then carried by the drawing */
.vis-at { position: absolute; width: 0; height: 0; }
.at-par3 { left: 78.13%; top: 77.13%; }
.at-etix { left: 56.19%; top: 49.25%; }
.at-dc1 { left: 19.45%; top: 38.34%; }
.at-as0 { left: 92.94%; top: 36.96%; }
.at-as1 { left: 56.5%; top: 23.27%; }
.vis-ix { display: none; }
.world.is-live .vis-at { left: 0; top: 0; will-change: transform, opacity; }
.world.is-live .vis-ix { display: block; opacity: 0; }
.vl {
  position: absolute; top: 0; white-space: nowrap;
  font: 380 11.5px/1.35 var(--mono); font-stretch: 87.5%; letter-spacing: .01em; font-variant-numeric: slashed-zero;
  color: var(--graphite); text-shadow: 0 0 6px var(--ink), 0 1px 2px var(--ink);
}
.vl b { display: block; font-weight: 460; color: var(--chalk); }
.vl-r { left: 15px; transform: translateY(-50%); }
.vl-l { right: 15px; transform: translateY(-50%); text-align: right; }
.vl-b { left: 0; top: 13px; transform: translateX(-50%); text-align: center; }
.vl-bl { right: 13px; top: 6px; text-align: right; }
.vl-a { left: 0; top: -13px; transform: translate(-50%, -100%); text-align: center; }
.vl-t { left: 0; top: -12px; transform: translate(-50%, -100%); color: var(--lamp); }

/* ---------- The pause control, in the bottom-right corner of the hero (BRIEF §0.10.4.e) ---------- */
.vis-ui {
  position: fixed; z-index: 1;
  right: 0; bottom: 0;
  padding: 0 calc(16px + var(--sr)) calc(16px + var(--sb)) 0;
  display: flex; justify-content: flex-end; align-items: flex-end;
  pointer-events: none;
}
.vis-ui > * { pointer-events: auto; }
/* the author display must never beat the hidden attribute */
[hidden] { display: none !important; }
/* without JS the copy buttons would do nothing; visibility keeps the layout identical */
html:not(.js) .copy { visibility: hidden; }
/* one pause control for all that moves (WCAG 2.2.2); pressed, it turns to the lamp */
.pause {
  display: none; place-items: center; flex: none; margin-left: auto;
  width: 44px; height: 44px; padding: 0;
  border: 1px solid var(--rule); border-radius: 50%;
  background: var(--plate-strong); color: var(--graphite);
  cursor: pointer; transition: border-color .2s, color .2s;
}
.js .pause { display: inline-grid; }
.pause:hover { color: var(--chalk); border-color: var(--graphite); }
.pause svg { width: 1rem; height: 1rem; fill: none; stroke: currentColor; stroke-width: 1.6; }
.pause .i-play { display: none; fill: currentColor; stroke: none; }
.pause[aria-pressed="true"] { color: var(--lamp); }
.pause[aria-pressed="true"] .i-pause { display: none; }
.pause[aria-pressed="true"] .i-play { display: inline; }
/* reduced motion: nothing moves, so there is nothing to pause */
@media (prefers-reduced-motion: reduce) { .js .pause { display: none; } }


/* ---------- Header ---------- */
/* BRIEF §0.4: the wordmark is sized like a logo, not like a link. Martian Mono caps are 0.80 em:
   20 px type at 390 px gives a 16 px cap, 30 px from 1024 px gives a 24 px cap.
   One alignment for the whole header, the optical centre: at line-height 1 the mono's caps sit
   centred in their box, and the lit-square sign, the link plates and the caps share one centre line. */
.top {
  position: absolute; z-index: 4; top: 0; left: 0; right: 0; view-transition-name: top;
  display: flex; align-items: center; gap: 1.5rem;
  min-height: calc(var(--head) + var(--st));
  padding: var(--st) calc(var(--pad) + var(--sr)) 0 calc(var(--pad) + var(--sl));
  pointer-events: none;
}
.top > * { pointer-events: auto; }
.mark { display: inline-flex; align-items: center; gap: .36em; min-height: 44px; text-decoration: none; font: 460 clamp(1.25rem, .866rem + 1.577vw, 1.875rem)/1 var(--mono); font-stretch: 87.5%; letter-spacing: .02em; }
/* three lit data centres on one fibre: the sign's ink spans 18 of its 20 units, so at .89em it is exactly the cap height */
.mark-sign { flex: none; width: .89em; height: .89em; }
.bm-on { fill: var(--lamp); }
.bm-fibre { fill: none; stroke: var(--lamp); stroke-width: 1.3; stroke-linecap: round; opacity: .6; }
/* plain links, no plates: 44 px targets, underlined on hover and focus only; an ink halo keeps them clear of the drawing */
.nav { display: flex; gap: 1.4rem; margin-left: auto; }
.nav a, .lang {
  display: inline-flex; align-items: center; justify-content: center; min-height: 44px; min-width: 44px;
  font-size: .95rem; color: var(--graphite); text-decoration: none; text-shadow: 0 0 10px var(--ink), 0 0 3px var(--ink);
}
.nav a:hover, .lang:hover, .nav a:focus-visible, .lang:focus-visible { color: var(--chalk); text-decoration: underline; text-decoration-color: var(--lamp); text-underline-offset: .3em; }
.nav a[aria-current="page"] { color: var(--chalk); }
.lang { color: var(--chalk); }
.lang.is-offered { animation: offer 2.4s ease-in-out 1.2s 1 both; }
@keyframes offer {
  0%, 100% { text-shadow: none; }
  45% { text-shadow: 0 0 14px var(--lamp-glow); color: var(--lamp); }
}

/* ---------- Content ---------- */
/* the page lets pointers through except where there is content */
main, .hero { pointer-events: none; }
main { position: relative; z-index: 2; }
.panel { position: relative; pointer-events: auto; }
.window { display: none; }

h1 {
  margin: 0;
  font-family: var(--mono);
  font-stretch: 75%;
  font-weight: 230;
  font-size: clamp(3.9rem, 8.6vw, 8.4rem);
  line-height: .92;
  letter-spacing: -.035em;
  font-variant-numeric: slashed-zero;
  color: var(--chalk);
}
.h1-sub { margin: .8rem 0 0; max-width: 30rem; font: 440 clamp(1.5rem, 2.4vw, 2.25rem)/1.12 var(--sans); letter-spacing: -.01em; color: var(--chalk); text-wrap: balance; }
.lede { margin: 1.6rem 0 0; max-width: 31rem; font-size: 1.3rem; line-height: 1.45; font-weight: 380; color: var(--chalk); }
h2 { margin: 0 0 1.1rem; font-size: 1.75rem; line-height: 1.15; font-weight: 520; letter-spacing: -.01em; }
p { margin: 0 0 1rem; max-width: 36rem; }
sup { font-size: .68em; line-height: 0; }
strong { font-weight: 620; }

.facts { margin: 1.4rem 0; }
.facts > div, .steps > li {
  display: grid; grid-template-columns: 8.5rem minmax(0, 1fr); gap: 1rem;
  padding: .58rem 0; border-top: 1px solid var(--rule);
}
.facts > div:last-child, .steps > li:last-child { border-bottom: 1px solid var(--rule); }
.steps { margin: 1.4rem 0; padding: 0; list-style: none; }
.steps .v { color: var(--chalk); font-size: .92rem; padding-top: .1rem; }
.facts dt { color: var(--graphite); font-size: .9rem; font-weight: 460; padding-top: .12rem; }
.facts dd { margin: 0; min-width: 0; overflow-wrap: anywhere; }
.stack { display: grid; gap: .2rem; }
.stack .line { display: inline-flex; align-items: center; gap: .1rem; }
.stack .sub { color: var(--graphite); font-size: .92rem; }
.stack .line:has(.up) { flex-wrap: wrap; }
.stack .line .up { flex-basis: 100%; margin: 0 0 .15rem; color: var(--graphite); font-size: .92rem; }
.lamp { display: inline-block; flex: none; width: .62rem; height: .62rem; margin-right: .6rem; background: var(--lamp); box-shadow: 0 0 10px var(--lamp-glow); }

.asof { margin-top: 1rem; font-size: .92rem; color: var(--graphite); }
.ops { margin: 0; max-width: 34rem; }

.copy {
  position: relative; flex: none;
  display: inline-grid; place-items: center; vertical-align: middle;
  width: 2rem; height: 2rem; margin: -.3rem 0 -.3rem .35rem; padding: 0;
  border: 0; border-radius: 3px; background: transparent; color: var(--graphite);
  cursor: pointer; transition: color .2s;
}
.copy::before, .copy::after {
  content: ""; position: absolute; width: .5rem; height: .5rem;
  border: 1.3px solid currentColor; transition: background-color .2s, border-color .2s, box-shadow .3s;
}
.copy::before { transform: translate(.28rem, -.28rem); }
.copy::after { transform: translate(-.28rem, .28rem); }
.copy:hover { color: var(--chalk); }
.copy.is-copied { color: var(--lamp); }
.copy.is-copied::before, .copy.is-copied::after { background: var(--lamp); border-color: var(--lamp); box-shadow: 0 0 8px var(--lamp-glow); }
.copy .copied { position: absolute; left: 100%; top: 50%; transform: translateY(-50%); padding-left: .1rem; font: 460 .8rem/1 var(--sans); color: var(--lamp); white-space: nowrap; pointer-events: none; }
.copy-text { width: auto; padding: 0 .2rem 0 2rem; font: 460 .8rem/1 var(--sans); }
.copy-text::before, .copy-text::after { left: .75rem; top: calc(50% - .25rem); }
.copy-text::before { transform: translate(.28rem, -.28rem); }
.copy-text::after { transform: translate(-.28rem, .28rem); }
@media (pointer: coarse) {
  .copy { width: 2.75rem; height: 2.75rem; margin-block: -.6rem; }
  td .copy { margin-right: -.6rem; }
  .copy-text { width: auto; height: 2.75rem; }
}

.sec { padding-top: 1px; }
.prefix { margin: 2.2rem 0 0; }
.prefix-name { display: flex; align-items: center; margin: 0; font-size: 1.45rem; }
.prefix-name .v { font-size: 1em; font-weight: 400; }
.prefix .facts { margin-top: .8rem; }
.note { color: var(--graphite); font-size: .95rem; }
.note strong { color: var(--chalk); font-weight: 560; }

.table-wrap { overflow-x: auto; margin: 1.4rem 0; }
.upstreams { width: 100%; border-collapse: collapse; font-size: 1rem; }
.upstreams th { text-align: left; font-weight: 460; font-size: .9rem; color: var(--graphite); padding: 0 1rem .5rem 0; }
.upstreams td { padding: .62rem 1rem .62rem 0; border-top: 1px solid var(--rule); vertical-align: baseline; }
.upstreams tr:last-child td { border-bottom: 1px solid var(--rule); }
.upstreams td:first-child { white-space: nowrap; }
/* the table's last rule already closes it off from the list below: one rule, not two */
.table-wrap + .facts > div:first-child { border-top: 0; }

.rpsl { position: relative; margin: 1.8rem 0 1.4rem; }
.rpsl figcaption { font-size: .9rem; color: var(--graphite); margin-bottom: .6rem; padding-right: 7rem; }
.rpsl .copy-text { position: absolute; right: 0; top: -.35rem; height: 2rem; margin: 0; }
@media (pointer: coarse) { .rpsl .copy-text { height: 44px; min-width: 44px; top: -.8rem; } .rpsl figcaption { margin-bottom: .8rem; } }
.rpsl pre {
  margin: 0; padding: 1.05rem 1.2rem; overflow-x: auto;
  background: var(--ink-deep); border: 1px solid var(--rule); border-radius: 3px;
  font: 380 .86rem/1.7 var(--mono); font-stretch: 87.5%; font-variant-numeric: slashed-zero; color: var(--chalk);
  tab-size: 4;
}

.links { list-style: none; margin: 1.4rem 0; padding: 0; }
.links li { border-top: 1px solid var(--rule); }
.links li:last-child { border-bottom: 1px solid var(--rule); }
.links a { display: flex; justify-content: space-between; align-items: baseline; gap: 1rem; flex-wrap: wrap; padding: .75rem 0; text-decoration: none; }
.links .lu { font: 380 .82rem/1.3 var(--mono); font-stretch: 87.5%; color: var(--graphite); }
.links a:hover .ln { text-decoration: underline; text-decoration-color: var(--lamp); text-underline-offset: .22em; }
.links a:hover .lu { color: var(--chalk); }


/* ---------- Data centres, exchanges, capacity ---------- */
.nw { white-space: nowrap; }
/* a data centre: the lit junction of the drawing */
.node { display: inline-block; flex: none; width: .44rem; height: .44rem; margin: 0 .75rem 0 .12rem; border-radius: 50%; background: var(--lamp); box-shadow: 0 0 0 .2rem var(--ink), 0 0 0 calc(.2rem + 1px) var(--lamp-glow), 0 0 10px var(--lamp-glow); vertical-align: .08em; }
.dcs td:first-child { font-weight: 460; }
.reg td { white-space: nowrap; }
.reg .valid { font-weight: 520; }
/* joining an exchange: an unlit ring */
.joining { display: inline-flex; align-items: center; gap: .45rem; margin-left: .55rem; color: var(--graphite); font-size: .92em; }
.joining::before { content: ""; width: .5rem; height: .5rem; border: 1.3px solid var(--lamp); border-radius: 50%; flex: none; }
td > .joining { margin-left: 0; }
.stack .line:has(.joining) { flex-wrap: wrap; white-space: nowrap; } /* a narrow column: the exchange keeps its name whole, its state goes under it */


/* capacities: the figure first, large, in the mono */
.cap { margin: 1.4rem 0; display: grid; grid-template-columns: repeat(auto-fit, minmax(9.5rem, 1fr)); gap: 0 1.5rem; }
.cap > div { display: flex; flex-direction: column; justify-content: space-between; padding: .7rem 0 .9rem; border-top: 1px solid var(--rule); border-bottom: 1px solid var(--rule); }
.cap dt { color: var(--graphite); font-size: .9rem; font-weight: 460; }
.cap dd { margin: .9rem 0 0; white-space: nowrap; }
.cap-n { font: 250 2.9rem/1 var(--mono); font-stretch: 75%; letter-spacing: -.03em; color: var(--chalk); font-variant-numeric: tabular-nums slashed-zero; }
.cap-w { font: 300 1.5rem/1.2 var(--mono); font-stretch: 87.5%; color: var(--chalk); }
.cap-u { font: 400 .95rem/1 var(--mono); font-stretch: 87.5%; color: var(--graphite); }

.foot { position: relative; z-index: 2; display: flex; flex-wrap: wrap; gap: .5rem 2rem; padding: 2.5rem calc(var(--pad) + var(--sr)) calc(3rem + var(--sb)) calc(var(--pad) + var(--sl)); font-size: .92rem; color: var(--graphite); }
.foot p { margin: 0; }
.foot a { text-decoration-color: var(--rule); }
.foot a:hover { color: var(--chalk); }
.foot .foot-facts { flex-basis: 100%; order: 3; font-size: .85rem; }
.foot .foot-facts:empty { display: none; }

/* ---------- Desktop: text column on the left, the drawing on the right ---------- */
@media (min-width: 1024px) {
  main { width: calc(var(--pad) + var(--sl) + var(--col)); padding-left: calc(var(--pad) + var(--sl)); }
  .hero { min-height: 100vh; min-height: 100svh; padding-top: calc(var(--head) + var(--st) + 5vh - 1rem); padding-bottom: 8vh; }
  .sec { padding-block: 10vh 5vh; }
  .sec-last { padding-bottom: 14vh; }
  .foot { width: calc(var(--pad) + var(--sl) + var(--col)); }
  .hero-facts .ops { margin-top: 2.6rem; }
  .hero-facts .glance { margin-top: 1.8rem; }
}
/* without the live drawing, or in high contrast, the sections need no room to breathe for it */
html:not(.js) .sec { padding-block: 4rem 0; }
@media (forced-colors: active) { .sec { padding-block: 4rem 0; } }

/* ---------- Phone and tablet: opaque panels, windows onto the drawing ---------- */
@media (max-width: 1023.98px) {
  :root {
    --col: 100vw;
    --fl: 0px;
    --fw: 100vw;
    --ft: 0px;
    --fh: var(--win-h, 56svh);
    --ps: calc(min(var(--fw), var(--fh)) * .9);
  }
  /* the drawing sits in the window being looked through and scrolls with it; the others hold the poster */
  .world { position: absolute; inset: auto; left: 0; top: var(--win-top, 0px); width: 100%; height: var(--fh); background: var(--ink); }
  .js main .window { background: url("/assets/vision.svg") 50% 50% / calc(min(100vw, 58svh) * .9) no-repeat; }
  .js main .window-hero { background-size: calc(min(100vw, var(--hero-h, 56svh)) * .9); }
  .js main .window.is-framed { background: none; }
  .world:not(.is-live) ~ .vis-ui { visibility: hidden; }
  .panel { background: var(--ink); padding-inline: calc(var(--pad) + var(--sl)) calc(var(--pad) + var(--sr)); }
  .panel > * { max-width: 40rem; }
  /* the first screen: the words, then the drawing down to the bottom of the small viewport */
  .hero-first { display: flex; flex-direction: column; min-height: 100vh; min-height: 100svh; }
  .hero-text { padding-top: calc(var(--head) + var(--st) + .5rem); padding-bottom: 1.4rem; }
  .window { display: block; height: 58svh; pointer-events: none; }
  .window-hero { flex: 1 0 auto; height: auto; min-height: max(14rem, 40svh); }
  .hero > .panel:last-child { padding-top: 1.4rem; padding-bottom: 2.4rem; }
  .sec { padding-block: 2.5rem 2rem; }
  .nav { gap: 1.1rem; }
  /* the pause control rides with the drawing: bottom-right of the window it is in, the hero's first */
  .vis-ui { position: absolute; left: 0; right: 0; top: var(--win-top, 0px); bottom: auto; height: var(--fh); }
  .vl { font-size: 10.5px; }
  .at-as0 .vl { width: min-content; white-space: normal; } /* one word a line, clear of the secondary bundle */
  .at-ix0 .vl { transform: translate(-12px, -100%); } /* the exchanges' names start at their points, clear of the edge and of each other */
  .at-ix1 .vl { top: -22px; transform: translate(-30%, -100%); }
  .at-par3 .vl { left: auto; right: 2px; top: 12px; transform: none; text-align: right; } /* under its site, clear of the pause */
  .glance { margin-top: 0; }
  .ops + .glance { margin-top: 1.4rem; }
  .foot { padding-top: 2rem; }
  .facts > div, .steps > li { grid-template-columns: 6.6rem minmax(0, 1fr); gap: .8rem; }
  /* without JS nothing follows the scroll: the hero window carries the still drawing */
  html:not(.js) .world:not(.world-still), html:not(.js) .vis-ui, html:not(.js) main .window:not(.window-hero) { display: none; }
  html:not(.js) .window-hero { background: url("/assets/vision.svg") 50% 50% / contain no-repeat; }
  .world-still { display: none; }
}
/* a phone on its side: the header keeps the phone's height */
@media (max-width: 1023.98px) and (max-height: 500px) { :root { --head: 76px; } }
/* a small drawing: the transit links keep to their numbers (the facts beside it say which is primary) */
@media (max-width: 599.98px), (max-width: 1023.98px) and (max-height: 500px) {
  .at-as0 .vl, .at-as1 .vl { font-size: 0; }
  .at-as0 .vl b, .at-as1 .vl b { font-size: 10.5px; }
}
/* phone: the first screen holds the name, the sentence and the drawing; the facts follow it */
@media screen and (max-width: 599.98px) {
  h1 { font-size: 3.2rem; }
  .hero-text { padding-top: calc(var(--head) + var(--st) + .25rem); padding-bottom: 1.1rem; }
  .lede { margin-top: .9rem; }
  .facts.glance > div { grid-template-columns: 5.4rem minmax(0, 1fr); gap: .6rem; }
  /* tables become stacked rows: the first cell names the row, the others follow with their column's name */
  .upstreams, .upstreams tbody, .upstreams tr, .upstreams td { display: block; }
  .upstreams thead { display: none; }
  .upstreams tr { display: flex; flex-wrap: wrap; gap: .35rem 1.6rem; padding: .7rem 0 .8rem; border-top: 1px solid var(--rule); }
  .upstreams tr:last-child { border-bottom: 1px solid var(--rule); }
  .upstreams td, .upstreams tr:last-child td { padding: 0; border: 0; }
  .upstreams td:first-child { flex-basis: 100%; display: flex; align-items: center; font-weight: 460; }
  .upstreams td[data-label]::before { content: attr(data-label); display: block; margin-bottom: .1rem; font: 460 .8rem/1.3 var(--sans); color: var(--graphite); }
}
/* below 768 px the wordmark and the four section links no longer fit on one line: the header keeps Contact and
   the language (the sections follow one another down the page), on one line down to 320 px */
@media (max-width: 767.98px) { .nav a:not(.nav-contact) { display: none; } .top { gap: 1.1rem; } }
@media (max-width: 374.98px) { .top { gap: .75rem; } }
@media (max-width: 420px) {
  .lede { font-size: 1.14rem; }
  h2 { font-size: 1.5rem; }
  .prefix-name { font-size: 1.12rem; }
  .facts > div, .steps > li { grid-template-columns: 1fr; gap: .15rem; }
  /* narrow French column: hyphenate prose only, never data */
  :lang(fr) p, :lang(fr) dd:not(:has(.v)), :lang(fr) li { hyphens: auto; hyphenate-limit-chars: 10 4 4; }
  :lang(fr) .v, :lang(fr) code, :lang(fr) a { hyphens: manual; }
  :lang(fr) :is(.lede, .h1-sub, h1, h2, h3, .prefix-name) { hyphens: manual; } /* never the lede or headings */
}
/* 320 px: the facts at a glance stack too, so a prefix stays on one line beside its copy button */
@media (max-width: 359.98px) { .facts.glance > div { grid-template-columns: 1fr; gap: .15rem; } }

/* ---------- Legal pages and 404: text only, the drawing as a still backdrop ---------- */
.doc { position: relative; z-index: 2; width: auto; max-width: 46rem; padding: calc(var(--head) + var(--st) + 1.75rem) calc(var(--pad) + var(--sr)) 4rem calc(var(--pad) + var(--sl)); pointer-events: auto; }
.mark + .lang { margin-left: auto; }
/* on the legal pages and the 404 the drawing is a still print, on the right */
.world-still .vis-poster { opacity: .8; }
.doc h1 { font-size: clamp(2.8rem, 6vw, 4.6rem); margin-bottom: 2.4rem; }
.doc h1 + .asof { margin: -1.4rem 0 2.2rem; }
.doc h2 { font-size: 1.3rem; margin-top: 2.6rem; margin-bottom: .6rem; }
.doc p, .doc li { max-width: 40rem; }
.doc ul { padding-left: 1.1rem; }
.doc .facts { margin-top: .6rem; }
.doc .facts > div { grid-template-columns: 11.5rem minmax(0, 1fr); }
@media (max-width: 640px) { .doc .facts > div { grid-template-columns: 1fr; gap: .15rem; } }
.tbc { color: var(--lamp); font-family: var(--mono); font-stretch: 87.5%; font-size: .9em; }

/* ---------- Contact form ---------- */
.contact { position: relative; margin: 2.2rem 0 0; max-width: 34rem; }
.contact p { margin: 0 0 1.15rem; }
.contact label { display: block; margin-bottom: .35rem; font-size: .9rem; font-weight: 460; color: var(--graphite); }
.contact input, .contact textarea {
  display: block; width: 100%; padding: .62rem .75rem;
  font: 400 1rem/1.4 var(--sans); color: var(--chalk);
  background: var(--ink-deep); border: 1px solid var(--rule); border-radius: 3px;
  transition: border-color .2s;
}
.contact textarea { resize: vertical; min-height: 10rem; }
.contact input:hover, .contact textarea:hover { border-color: var(--graphite); }
.contact input:focus-visible, .contact textarea:focus-visible { outline: 2px solid var(--lamp); outline-offset: 1px; border-color: var(--ink-deep); }
.contact input:user-invalid, .contact textarea:user-invalid { border-color: var(--lamp); }
.contact .asn { max-width: 14rem; font-family: var(--mono); font-stretch: 87.5%; font-variant-numeric: slashed-zero; }
.contact-trap { position: absolute; left: -100vw; }
.contact-note { font-size: .9rem; color: var(--graphite); }
.contact button[type="submit"] {
  min-height: 2.75rem; padding: 0 1.5rem;
  font: 540 1rem/1 var(--sans); color: var(--ink); background: var(--chalk);
  border: 0; border-radius: 3px; cursor: pointer; transition: background-color .2s;
}
.contact button[type="submit"]:hover { background: var(--lamp); }
.contact button[type="submit"]:disabled { opacity: .6; cursor: progress; }
.contact-status { min-height: 1.55em; margin-top: 1rem; color: var(--chalk); }
.doc .lede-doc { font-size: 1.12rem; }
.lost { min-height: 100svh; display: grid; align-content: center; padding-block: var(--head) 4rem; }
/* the 404 sits on a plate over the still drawing, like the pause control */
.lost-plate { max-width: 38rem; padding: 1.8rem 2rem 1.6rem; background: var(--plate-strong); border: 1px solid var(--rule); border-radius: 3px; }
.doc .lost-code { font-size: clamp(1.9rem, 3.9vw, 3.3rem); line-height: 1.05; letter-spacing: -.03em; margin-bottom: 1.2rem; }
.lost-line { font-size: 1.12rem; margin-bottom: .45rem; }
.lost-line:last-child { margin-bottom: 0; }
.lost-fr { color: var(--graphite); }
.lost-fr a { color: var(--chalk); }
@media (max-width: 1023.98px) {
  /* on a phone the still drawing stays, under the plate: no empty ink screen */
  .world-still.world-lost { display: block; }
  .lost { min-height: 0; align-content: start; }
  .lost-plate { padding: 1.3rem 1.2rem 1.2rem; }
}

/* ---------- Forced colours: the text, in system colours; the drawing steps aside ---------- */
@media (forced-colors: active) {
  .world, .vis-ui, .window { display: none !important; }
  .panel, .foot, .doc, .nav, .lang { background: Canvas; }
  .lamp, .node, .mark-sign { forced-color-adjust: none; }
  .lamp, .node { background: Highlight; box-shadow: none; }
  .bm-on { fill: Highlight; }
  .bm-fibre { stroke: CanvasText; opacity: 1; }
  .copy { color: ButtonText; }
  .copy.is-copied::before, .copy.is-copied::after { background: Highlight; border-color: Highlight; box-shadow: none; }
  .copy .copied { color: Highlight; }
  .rpsl pre, .contact input, .contact textarea { border-color: CanvasText; }
  .joining::before { border-color: CanvasText; }
  .pause { display: none !important; }
  :focus-visible { outline-color: Highlight; }
}

/* ---------- More contrast: brighter secondary text, solid plates ---------- */
@media (prefers-contrast: more) {
  :root { --graphite: oklch(88% 0.012 222); --rule: oklch(58% 0.03 223); --plate: var(--ink-deep); --plate-strong: var(--ink-deep); }
  .panel { background: var(--ink); }
  .vl { color: var(--chalk); }
  a { text-decoration-color: currentColor; }
}

/* ---------- Print: NOC engineers print this page. Black on white, every URL spelled out ---------- */
@media print {
  @page { margin: 15mm 14mm 16mm; }
  :root { color-scheme: light; background: white; --ink: white; --ink-deep: white; --chalk: black; --graphite: #3d3d3d; --rule: #b8b8b8; --lamp: black; --lamp-glow: transparent; --plate: white; --plate-strong: white; }
  html, body { background: white; color: black; }
  body { font-size: 10.5pt; line-height: 1.45; }
  .world, .vis-ui, .window, .skip, .nav, .lang, .copy, .lamp, .node, [data-live] { display: none !important; }
  .cap > div { break-inside: avoid; }
  .cap-n { font-size: 22pt; color: black; }
  .cap-w { color: black; }
  .top { position: static; min-height: 0; padding: 0 0 5mm; }
  .mark { font-size: 18pt; min-height: 0; }
  main, .foot, .doc { width: auto; max-width: none; margin: 0; padding: 0; }
  .panel { background: none; padding: 0; }
  .panel > * { max-width: none; }
  .hero { min-height: 0; padding: 0; }
  .hero-text { padding: 0; }
  .sec, .sec-last { padding: 7mm 0 0; }
  h1 { font-size: 34pt; line-height: 1; }
  .doc h1 { font-size: 26pt; margin-bottom: 6mm; }
  h2 { font-size: 14pt; margin-bottom: 3mm; break-after: avoid; }
  .lede { max-width: none; margin-top: 3mm; font-size: 12pt; }
  p { max-width: none; }
  .glance, .ops { margin-top: 5mm; }
  .hero > .panel:last-child { padding: 0; }
  .facts > div { grid-template-columns: 34mm minmax(0, 1fr); gap: 4mm; padding: 1.6mm 0; }
  .facts > div, tr, .prefix-name, .rpsl, .links li { break-inside: avoid; }
  .prefix { margin-top: 5mm; }
  .prefix-name { font-size: 12pt; }
  .valid { color: black; font-weight: 640; }
  .rpsl pre { background: none; border: 1px solid #8a8a8a; white-space: pre-wrap; font-size: 9pt; }
  .rpsl figcaption { padding-right: 0; }
  .table-wrap { overflow: visible; }
  a { color: black; text-decoration: underline; text-decoration-color: #8a8a8a; }
  a[href^="http"]::after { content: " (" attr(href) ")"; font: 400 8.5pt/1.3 var(--mono); font-stretch: 87.5%; color: #3d3d3d; overflow-wrap: anywhere; }
  a[href^="/"]::after { content: " (https://www.as201040.net" attr(href) ")"; font: 400 8.5pt/1.3 var(--mono); font-stretch: 87.5%; color: #3d3d3d; overflow-wrap: anywhere; }
  .links a { display: block; padding: 1.8mm 0; }
  .links .lu { display: none; }
  .foot { display: block; margin-top: 8mm; padding-top: 3mm; border-top: 1px solid #b8b8b8; font-size: 9pt; }
  .foot p { display: inline; margin-right: 6mm; }
}
