<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>Londology</title>
    <link>https://londology.co.uk/</link>
    <atom:link href="https://londology.co.uk/rss.xml" rel="self" type="application/rss+xml"/>
    <description>An independent visual-data magazine about London: original analyses of open data, interactive maps, and rigorously footnoted curiosities.</description>
    <language>en-GB</language>
    <copyright>Text and charts by Londology, free to reuse with credit. Datasets keep their own licences.</copyright>
    <item>
      <title>Every number on this page is invented</title>
      <link>https://londology.co.uk/data/design-system-sample/</link>
      <guid isPermaLink="true">https://londology.co.uk/data/design-system-sample/</guid>
      <pubDate>Sun, 16 Aug 2026 00:00:00 GMT</pubDate>
      <description>A sample piece that exercises every component in the design system, built from a formula rather than from data, so that nothing here can be mistaken for a finding about London.</description>
      <category>data</category>
      <category>maps-of-maps</category>
      <content:encoded><![CDATA[<p>This page exists to prove that the design system works, and to prove it on a
page rather than in a description. It uses every component the system has: two
figures, three confidence marks, a map that costs nothing until you ask for it,
and the block that closes every analysis.</p>
<span class="claim" data-astro-cid-sbzmajdw> <p>Every value below comes from a formula in <code>pipeline/design-system-sample/fetch.py</code>,
not from a measurement.</p> <a class="claim-badge claim-fact" href="/methods/#fact" title="What &#34;Fact&#34; means here" data-astro-cid-sbzmajdw> Fact </a>  </span> 
<p>The reason for that is not laziness. This repository sells itself on
verifiability, and a plausible-looking number about London sitting in a sample
file is a small time bomb: someone quotes it, and the site’s one real asset is
gone. Synthetic data cannot be misquoted, because it says what it is.</p>
<figure id="three-series" class="my-10 figure-wide" aria-labelledby="three-series-title" data-astro-cid-bj3fsypb> <figcaption class="mb-3 font-apparatus" data-astro-cid-bj3fsypb> <strong id="three-series-title" class="block text-[0.95rem] font-semibold text-ink" data-astro-cid-bj3fsypb>Three synthetic series, twelve months</strong> <span class="mt-0.5 block text-[0.85rem] leading-snug text-ink-muted" data-astro-cid-bj3fsypb>Named after boroughs so the chart has plausible labels. It measures nothing.</span> </figcaption>  <div class="figure-canvas" role="img" aria-label="Three invented series over 2026, each rising to a peak in a different month and falling back, with Hackney highest throughout." data-astro-cid-bj3fsypb> <svg role="img" style="background:transparent;color:#1a1a19;font-family:'Londology Sans', 'IBM Plex Sans', 'Helvetica Neue', 'Segoe UI', Roboto, Arial, sans-serif;font-size:13px;font-variant-numeric:tabular-nums;overflow:visible;width:100%;height:auto;max-width:900px" aria-label="Three invented series over 2026, each peaking in a different month." viewBox="0 0 900 340" height="340" text-anchor="middle" font-size="10" font-family="system-ui, sans-serif" fill="currentColor" class="plot-d6a7b5"><style>:where(.plot-d6a7b5) {
  --plot-background: white;
  display: block;
  height: auto;
  height: intrinsic;
  max-width: 100%;
}
:where(.plot-d6a7b5 text),
:where(.plot-d6a7b5 tspan) {
  white-space: pre;
}</style><g stroke="currentColor" fill="none" aria-hidden="true"><path d="M0,0L-6,0" transform="translate(52,300)" /><path d="M0,0L-6,0" transform="translate(52,260)" /><path d="M0,0L-6,0" transform="translate(52,220)" /><path d="M0,0L-6,0" transform="translate(52,180)" /><path d="M0,0L-6,0" transform="translate(52,140)" /><path d="M0,0L-6,0" transform="translate(52,100)" /><path d="M0,0L-6,0" transform="translate(52,60.000000000000014)" /><path d="M0,0L-6,0" transform="translate(52,20)" /></g><g transform="translate(-9,0)" font-variant="tabular-nums" text-anchor="end"><text transform="translate(52,300)" y="0.32em">0</text><text transform="translate(52,260)" y="0.32em">10</text><text transform="translate(52,220)" y="0.32em">20</text><text transform="translate(52,180)" y="0.32em">30</text><text transform="translate(52,140)" y="0.32em">40</text><text transform="translate(52,100)" y="0.32em">50</text><text transform="translate(52,60.000000000000014)" y="0.32em">60</text><text transform="translate(52,20)" y="0.32em">70</text></g><g transform="translate(-49,-17)" text-anchor="start"><text transform="translate(52,20)" y="0.71em">↑ reading</text></g><g stroke="currentColor" fill="none" aria-hidden="true"><path d="M0,0L0,6" transform="translate(83,300)" /><path d="M0,0L0,6" transform="translate(145,300)" /><path d="M0,0L0,6" transform="translate(207,300)" /><path d="M0,0L0,6" transform="translate(269,300)" /><path d="M0,0L0,6" transform="translate(331,300)" /><path d="M0,0L0,6" transform="translate(393,300)" /><path d="M0,0L0,6" transform="translate(455,300)" /><path d="M0,0L0,6" transform="translate(517,300)" /><path d="M0,0L0,6" transform="translate(579,300)" /><path d="M0,0L0,6" transform="translate(641,300)" /><path d="M0,0L0,6" transform="translate(703,300)" /><path d="M0,0L0,6" transform="translate(765,300)" /></g><g transform="translate(0,9)"><text transform="translate(83,300)" y="0.71em">01</text><text transform="translate(145,300)" y="0.71em">02</text><text transform="translate(207,300)" y="0.71em">03</text><text transform="translate(269,300)" y="0.71em">04</text><text transform="translate(331,300)" y="0.71em">05</text><text transform="translate(393,300)" y="0.71em">06</text><text transform="translate(455,300)" y="0.71em">07</text><text transform="translate(517,300)" y="0.71em">08</text><text transform="translate(579,300)" y="0.71em">09</text><text transform="translate(641,300)" y="0.71em">10</text><text transform="translate(703,300)" y="0.71em">11</text><text transform="translate(765,300)" y="0.71em">12</text></g><g stroke="#d9d5cc"><line y2="300" y1="300" x2="796" x1="52" /></g><g stroke-linecap="round" stroke-linejoin="round" stroke-width="2.5" fill="none"><path d="M83,202.4L145,176L207,140L269,104L331,77.6L393,68L455,77.6L517,104L579,140L641,176L703,202.4L765,212" stroke="#1a1a19" /><path d="M83,188L145,178.4L207,152L269,116L331,80L393,53.6L455,44L517,53.6L579,80L641,116L703,152L765,178.4" stroke="#d55e00" /><path d="M83,154.4L145,164L207,154.4L269,128L331,92L393,56L455,29.6L517,20L579,29.6L641,56L703,92L765,128" stroke="#0072b2" /></g><g transform="translate(8,0)" font-size="13" text-anchor="start" fill="#1a1a19"><text transform="translate(765,212)" y="0.32em">Camden</text><text transform="translate(765,178.4)" y="0.32em">Southwark</text><text transform="translate(765,128)" y="0.32em">Hackney</text></g></svg> </div>  <p class="sr-only" data-astro-cid-bj3fsypb>Three invented series over 2026, each rising to a peak in a different month and falling back, with Hackney highest throughout.</p> <details class="mt-3 border-t border-rule pt-2 font-apparatus text-[0.8rem]" data-astro-cid-bj3fsypb> <summary class="text-ink-muted hover:text-ink" data-astro-cid-bj3fsypb>
The numbers behind this figure
</summary> <div class="mt-2 overflow-x-auto" data-astro-cid-bj3fsypb> <table id="three-series-table" class="w-full border-collapse text-left" data-astro-cid-bj3fsypb> <thead data-astro-cid-bj3fsypb> <tr data-astro-cid-bj3fsypb> <th scope="col" class="border-b border-rule px-2 py-1 font-semibold text-ink" data-astro-cid-bj3fsypb> Month </th><th scope="col" class="border-b border-rule px-2 py-1 font-semibold text-ink text-right" data-astro-cid-bj3fsypb> Camden </th><th scope="col" class="border-b border-rule px-2 py-1 font-semibold text-ink text-right" data-astro-cid-bj3fsypb> Southwark </th><th scope="col" class="border-b border-rule px-2 py-1 font-semibold text-ink text-right" data-astro-cid-bj3fsypb> Hackney </th> </tr> </thead> <tbody data-astro-cid-bj3fsypb> <tr data-astro-cid-bj3fsypb> <td class="border-b border-rule/60 px-2 py-1 text-ink-muted" data-astro-cid-bj3fsypb> 2026-01 </td><td class="border-b border-rule/60 px-2 py-1 text-ink-muted text-right" data-astro-cid-bj3fsypb> 24.4 </td><td class="border-b border-rule/60 px-2 py-1 text-ink-muted text-right" data-astro-cid-bj3fsypb> 28 </td><td class="border-b border-rule/60 px-2 py-1 text-ink-muted text-right" data-astro-cid-bj3fsypb> 36.4 </td> </tr><tr data-astro-cid-bj3fsypb> <td class="border-b border-rule/60 px-2 py-1 text-ink-muted" data-astro-cid-bj3fsypb> 2026-02 </td><td class="border-b border-rule/60 px-2 py-1 text-ink-muted text-right" data-astro-cid-bj3fsypb> 31 </td><td class="border-b border-rule/60 px-2 py-1 text-ink-muted text-right" data-astro-cid-bj3fsypb> 30.4 </td><td class="border-b border-rule/60 px-2 py-1 text-ink-muted text-right" data-astro-cid-bj3fsypb> 34 </td> </tr><tr data-astro-cid-bj3fsypb> <td class="border-b border-rule/60 px-2 py-1 text-ink-muted" data-astro-cid-bj3fsypb> 2026-03 </td><td class="border-b border-rule/60 px-2 py-1 text-ink-muted text-right" data-astro-cid-bj3fsypb> 40 </td><td class="border-b border-rule/60 px-2 py-1 text-ink-muted text-right" data-astro-cid-bj3fsypb> 37 </td><td class="border-b border-rule/60 px-2 py-1 text-ink-muted text-right" data-astro-cid-bj3fsypb> 36.4 </td> </tr><tr data-astro-cid-bj3fsypb> <td class="border-b border-rule/60 px-2 py-1 text-ink-muted" data-astro-cid-bj3fsypb> 2026-04 </td><td class="border-b border-rule/60 px-2 py-1 text-ink-muted text-right" data-astro-cid-bj3fsypb> 49 </td><td class="border-b border-rule/60 px-2 py-1 text-ink-muted text-right" data-astro-cid-bj3fsypb> 46 </td><td class="border-b border-rule/60 px-2 py-1 text-ink-muted text-right" data-astro-cid-bj3fsypb> 43 </td> </tr><tr data-astro-cid-bj3fsypb> <td class="border-b border-rule/60 px-2 py-1 text-ink-muted" data-astro-cid-bj3fsypb> 2026-05 </td><td class="border-b border-rule/60 px-2 py-1 text-ink-muted text-right" data-astro-cid-bj3fsypb> 55.6 </td><td class="border-b border-rule/60 px-2 py-1 text-ink-muted text-right" data-astro-cid-bj3fsypb> 55 </td><td class="border-b border-rule/60 px-2 py-1 text-ink-muted text-right" data-astro-cid-bj3fsypb> 52 </td> </tr><tr data-astro-cid-bj3fsypb> <td class="border-b border-rule/60 px-2 py-1 text-ink-muted" data-astro-cid-bj3fsypb> 2026-06 </td><td class="border-b border-rule/60 px-2 py-1 text-ink-muted text-right" data-astro-cid-bj3fsypb> 58 </td><td class="border-b border-rule/60 px-2 py-1 text-ink-muted text-right" data-astro-cid-bj3fsypb> 61.6 </td><td class="border-b border-rule/60 px-2 py-1 text-ink-muted text-right" data-astro-cid-bj3fsypb> 61 </td> </tr><tr data-astro-cid-bj3fsypb> <td class="border-b border-rule/60 px-2 py-1 text-ink-muted" data-astro-cid-bj3fsypb> 2026-07 </td><td class="border-b border-rule/60 px-2 py-1 text-ink-muted text-right" data-astro-cid-bj3fsypb> 55.6 </td><td class="border-b border-rule/60 px-2 py-1 text-ink-muted text-right" data-astro-cid-bj3fsypb> 64 </td><td class="border-b border-rule/60 px-2 py-1 text-ink-muted text-right" data-astro-cid-bj3fsypb> 67.6 </td> </tr><tr data-astro-cid-bj3fsypb> <td class="border-b border-rule/60 px-2 py-1 text-ink-muted" data-astro-cid-bj3fsypb> 2026-08 </td><td class="border-b border-rule/60 px-2 py-1 text-ink-muted text-right" data-astro-cid-bj3fsypb> 49 </td><td class="border-b border-rule/60 px-2 py-1 text-ink-muted text-right" data-astro-cid-bj3fsypb> 61.6 </td><td class="border-b border-rule/60 px-2 py-1 text-ink-muted text-right" data-astro-cid-bj3fsypb> 70 </td> </tr><tr data-astro-cid-bj3fsypb> <td class="border-b border-rule/60 px-2 py-1 text-ink-muted" data-astro-cid-bj3fsypb> 2026-09 </td><td class="border-b border-rule/60 px-2 py-1 text-ink-muted text-right" data-astro-cid-bj3fsypb> 40 </td><td class="border-b border-rule/60 px-2 py-1 text-ink-muted text-right" data-astro-cid-bj3fsypb> 55 </td><td class="border-b border-rule/60 px-2 py-1 text-ink-muted text-right" data-astro-cid-bj3fsypb> 67.6 </td> </tr><tr data-astro-cid-bj3fsypb> <td class="border-b border-rule/60 px-2 py-1 text-ink-muted" data-astro-cid-bj3fsypb> 2026-10 </td><td class="border-b border-rule/60 px-2 py-1 text-ink-muted text-right" data-astro-cid-bj3fsypb> 31 </td><td class="border-b border-rule/60 px-2 py-1 text-ink-muted text-right" data-astro-cid-bj3fsypb> 46 </td><td class="border-b border-rule/60 px-2 py-1 text-ink-muted text-right" data-astro-cid-bj3fsypb> 61 </td> </tr><tr data-astro-cid-bj3fsypb> <td class="border-b border-rule/60 px-2 py-1 text-ink-muted" data-astro-cid-bj3fsypb> 2026-11 </td><td class="border-b border-rule/60 px-2 py-1 text-ink-muted text-right" data-astro-cid-bj3fsypb> 24.4 </td><td class="border-b border-rule/60 px-2 py-1 text-ink-muted text-right" data-astro-cid-bj3fsypb> 37 </td><td class="border-b border-rule/60 px-2 py-1 text-ink-muted text-right" data-astro-cid-bj3fsypb> 52 </td> </tr><tr data-astro-cid-bj3fsypb> <td class="border-b border-rule/60 px-2 py-1 text-ink-muted" data-astro-cid-bj3fsypb> 2026-12 </td><td class="border-b border-rule/60 px-2 py-1 text-ink-muted text-right" data-astro-cid-bj3fsypb> 22 </td><td class="border-b border-rule/60 px-2 py-1 text-ink-muted text-right" data-astro-cid-bj3fsypb> 30.4 </td><td class="border-b border-rule/60 px-2 py-1 text-ink-muted text-right" data-astro-cid-bj3fsypb> 43 </td> </tr> </tbody> </table> </div> </details> <p class="mt-2 font-apparatus text-[0.78rem] leading-snug text-ink-muted" data-astro-cid-bj3fsypb> <span class="font-semibold" data-astro-cid-bj3fsypb>Source:</span>  <a href="https://github.com/sluvec/londology.co.uk" rel="noopener" data-astro-cid-bj3fsypb> Synthetic borough readings </a>  (CC0-1.0)  —  <a href="#behind-the-data" data-astro-cid-bj3fsypb>full attribution</a> </p> </figure> 
<p>Three things in that figure are contractual rather than decorative. The lines
are labelled where they end, so the reader never has to match a colour to a key
— colour is a second channel here, never the only one. The alt text describes
what the chart shows rather than what kind of chart it is. And the numbers are
underneath it, in a table, without a download.</p>
<span class="claim" data-astro-cid-sbzmajdw> <p>A direct label beats a legend on almost every chart this site will publish,
because it removes the step where a reader has to hold a colour in their head.</p> <a class="claim-badge claim-interpretation" href="/methods/#interpretation" title="What &#34;Interpretation&#34; means here" data-astro-cid-sbzmajdw> Interpretation </a>  </span> 
<h2 id="a-second-figure-a-second-licence">A second figure, a second licence</h2>
<p>The figure below draws on a different source, under a different licence. That
is the point of it: the attribution block at the end of the page groups sources
by licence, and a stack that has only ever been tested with one licence has not
been tested at all.</p>
<figure id="river-levels" class="my-10" aria-labelledby="river-levels-title" data-astro-cid-bj3fsypb> <figcaption class="mb-3 font-apparatus" data-astro-cid-bj3fsypb> <strong id="river-levels-title" class="block text-[0.95rem] font-semibold text-ink" data-astro-cid-bj3fsypb>A single invented series</strong> <span class="mt-0.5 block text-[0.85rem] leading-snug text-ink-muted" data-astro-cid-bj3fsypb>One source, one licence, so the source line below names only one.</span> </figcaption>  <div class="figure-canvas" role="img" aria-label="An invented river level rising from 2.4 metres in January to a peak near 3.3 metres in July, then falling back by December." data-astro-cid-bj3fsypb> <svg role="img" style="background:transparent;color:#1a1a19;font-family:'Londology Sans', 'IBM Plex Sans', 'Helvetica Neue', 'Segoe UI', Roboto, Arial, sans-serif;font-size:13px;font-variant-numeric:tabular-nums;overflow:visible;width:100%;height:auto;max-width:640px" aria-label="An invented series rising to a mid-year peak and falling back." viewBox="0 0 640 260" height="260" text-anchor="middle" font-size="10" font-family="system-ui, sans-serif" fill="currentColor" class="plot-d6a7b5"><style>:where(.plot-d6a7b5) {
  --plot-background: white;
  display: block;
  height: auto;
  height: intrinsic;
  max-width: 100%;
}
:where(.plot-d6a7b5 text),
:where(.plot-d6a7b5 tspan) {
  white-space: pre;
}</style><g stroke="currentColor" fill="none" aria-hidden="true"><path d="M0,0L-6,0" transform="translate(52,220)" /><path d="M0,0L-6,0" transform="translate(52,159.3939393939394)" /><path d="M0,0L-6,0" transform="translate(52,98.78787878787878)" /><path d="M0,0L-6,0" transform="translate(52,38.181818181818166)" /></g><g transform="translate(-9,0)" font-variant="tabular-nums" text-anchor="end"><text transform="translate(52,220)" y="0.32em">0</text><text transform="translate(52,159.3939393939394)" y="0.32em">1</text><text transform="translate(52,98.78787878787878)" y="0.32em">2</text><text transform="translate(52,38.181818181818166)" y="0.32em">3</text></g><g transform="translate(-49,-17)" text-anchor="start"><text transform="translate(52,20)" y="0.71em">↑ metres</text></g><g transform="translate(20.5,0)" stroke="currentColor" fill="none" aria-hidden="true"><path d="M0,0L0,6" transform="translate(62,220)" /><path d="M0,0L0,6" transform="translate(108,220)" /><path d="M0,0L0,6" transform="translate(154,220)" /><path d="M0,0L0,6" transform="translate(200,220)" /><path d="M0,0L0,6" transform="translate(246,220)" /><path d="M0,0L0,6" transform="translate(292,220)" /><path d="M0,0L0,6" transform="translate(338,220)" /><path d="M0,0L0,6" transform="translate(384,220)" /><path d="M0,0L0,6" transform="translate(430,220)" /><path d="M0,0L0,6" transform="translate(476,220)" /><path d="M0,0L0,6" transform="translate(522,220)" /><path d="M0,0L0,6" transform="translate(568,220)" /></g><g transform="translate(20.5,9)"><text transform="translate(62,220)" y="0.71em">01</text><text transform="translate(108,220)" y="0.71em">02</text><text transform="translate(154,220)" y="0.71em">03</text><text transform="translate(200,220)" y="0.71em">04</text><text transform="translate(246,220)" y="0.71em">05</text><text transform="translate(292,220)" y="0.71em">06</text><text transform="translate(338,220)" y="0.71em">07</text><text transform="translate(384,220)" y="0.71em">08</text><text transform="translate(430,220)" y="0.71em">09</text><text transform="translate(476,220)" y="0.71em">10</text><text transform="translate(522,220)" y="0.71em">11</text><text transform="translate(568,220)" y="0.71em">12</text></g><g stroke="#d9d5cc"><line y2="220" y1="220" x2="620" x1="52" /></g><g fill="#0072b2"><rect height="145.45454545454547" y="74.54545454545453" width="41" x="62" /><rect height="159.3939393939394" y="60.6060606060606" width="41" x="108" /><rect height="172.72727272727275" y="47.272727272727245" width="41" x="154" /><rect height="184.24242424242425" y="35.75757575757575" width="41" x="200" /><rect height="192.72727272727275" y="27.272727272727252" width="41" x="246" /><rect height="198.1818181818182" y="21.81818181818181" width="41" x="292" /><rect height="200" y="20" width="41" x="338" /><rect height="198.1818181818182" y="21.81818181818181" width="41" x="384" /><rect height="192.72727272727275" y="27.272727272727252" width="41" x="430" /><rect height="184.24242424242425" y="35.75757575757575" width="41" x="476" /><rect height="172.72727272727275" y="47.272727272727245" width="41" x="522" /><rect height="159.3939393939394" y="60.6060606060606" width="41" x="568" /></g></svg> </div>  <p class="sr-only" data-astro-cid-bj3fsypb>An invented river level rising from 2.4 metres in January to a peak near 3.3 metres in July, then falling back by December.</p> <details class="mt-3 border-t border-rule pt-2 font-apparatus text-[0.8rem]" data-astro-cid-bj3fsypb> <summary class="text-ink-muted hover:text-ink" data-astro-cid-bj3fsypb>
The numbers behind this figure
</summary> <div class="mt-2 overflow-x-auto" data-astro-cid-bj3fsypb> <table id="river-levels-table" class="w-full border-collapse text-left" data-astro-cid-bj3fsypb> <thead data-astro-cid-bj3fsypb> <tr data-astro-cid-bj3fsypb> <th scope="col" class="border-b border-rule px-2 py-1 font-semibold text-ink" data-astro-cid-bj3fsypb> Month </th><th scope="col" class="border-b border-rule px-2 py-1 font-semibold text-ink text-right" data-astro-cid-bj3fsypb> Level (m) </th> </tr> </thead> <tbody data-astro-cid-bj3fsypb> <tr data-astro-cid-bj3fsypb> <td class="border-b border-rule/60 px-2 py-1 text-ink-muted" data-astro-cid-bj3fsypb> 2026-01 </td><td class="border-b border-rule/60 px-2 py-1 text-ink-muted text-right" data-astro-cid-bj3fsypb> 2.40 </td> </tr><tr data-astro-cid-bj3fsypb> <td class="border-b border-rule/60 px-2 py-1 text-ink-muted" data-astro-cid-bj3fsypb> 2026-02 </td><td class="border-b border-rule/60 px-2 py-1 text-ink-muted text-right" data-astro-cid-bj3fsypb> 2.63 </td> </tr><tr data-astro-cid-bj3fsypb> <td class="border-b border-rule/60 px-2 py-1 text-ink-muted" data-astro-cid-bj3fsypb> 2026-03 </td><td class="border-b border-rule/60 px-2 py-1 text-ink-muted text-right" data-astro-cid-bj3fsypb> 2.85 </td> </tr><tr data-astro-cid-bj3fsypb> <td class="border-b border-rule/60 px-2 py-1 text-ink-muted" data-astro-cid-bj3fsypb> 2026-04 </td><td class="border-b border-rule/60 px-2 py-1 text-ink-muted text-right" data-astro-cid-bj3fsypb> 3.04 </td> </tr><tr data-astro-cid-bj3fsypb> <td class="border-b border-rule/60 px-2 py-1 text-ink-muted" data-astro-cid-bj3fsypb> 2026-05 </td><td class="border-b border-rule/60 px-2 py-1 text-ink-muted text-right" data-astro-cid-bj3fsypb> 3.18 </td> </tr><tr data-astro-cid-bj3fsypb> <td class="border-b border-rule/60 px-2 py-1 text-ink-muted" data-astro-cid-bj3fsypb> 2026-06 </td><td class="border-b border-rule/60 px-2 py-1 text-ink-muted text-right" data-astro-cid-bj3fsypb> 3.27 </td> </tr><tr data-astro-cid-bj3fsypb> <td class="border-b border-rule/60 px-2 py-1 text-ink-muted" data-astro-cid-bj3fsypb> 2026-07 </td><td class="border-b border-rule/60 px-2 py-1 text-ink-muted text-right" data-astro-cid-bj3fsypb> 3.30 </td> </tr><tr data-astro-cid-bj3fsypb> <td class="border-b border-rule/60 px-2 py-1 text-ink-muted" data-astro-cid-bj3fsypb> 2026-08 </td><td class="border-b border-rule/60 px-2 py-1 text-ink-muted text-right" data-astro-cid-bj3fsypb> 3.27 </td> </tr><tr data-astro-cid-bj3fsypb> <td class="border-b border-rule/60 px-2 py-1 text-ink-muted" data-astro-cid-bj3fsypb> 2026-09 </td><td class="border-b border-rule/60 px-2 py-1 text-ink-muted text-right" data-astro-cid-bj3fsypb> 3.18 </td> </tr><tr data-astro-cid-bj3fsypb> <td class="border-b border-rule/60 px-2 py-1 text-ink-muted" data-astro-cid-bj3fsypb> 2026-10 </td><td class="border-b border-rule/60 px-2 py-1 text-ink-muted text-right" data-astro-cid-bj3fsypb> 3.04 </td> </tr><tr data-astro-cid-bj3fsypb> <td class="border-b border-rule/60 px-2 py-1 text-ink-muted" data-astro-cid-bj3fsypb> 2026-11 </td><td class="border-b border-rule/60 px-2 py-1 text-ink-muted text-right" data-astro-cid-bj3fsypb> 2.85 </td> </tr><tr data-astro-cid-bj3fsypb> <td class="border-b border-rule/60 px-2 py-1 text-ink-muted" data-astro-cid-bj3fsypb> 2026-12 </td><td class="border-b border-rule/60 px-2 py-1 text-ink-muted text-right" data-astro-cid-bj3fsypb> 2.63 </td> </tr> </tbody> </table> </div> </details> <p class="mt-2 font-apparatus text-[0.78rem] leading-snug text-ink-muted" data-astro-cid-bj3fsypb> <span class="font-semibold" data-astro-cid-bj3fsypb>Source:</span>  <a href="https://github.com/sluvec/londology.co.uk" rel="noopener" data-astro-cid-bj3fsypb> Synthetic river gauge series </a>  (CC-BY-4.0)  —  <a href="#behind-the-data" data-astro-cid-bj3fsypb>full attribution</a> </p> </figure> 
<h2 id="a-map-that-costs-nothing-until-you-ask">A map that costs nothing until you ask</h2>
<p>Maps load on intent. Before the button below is pressed, this page has fetched
no map library, no tiles and no geometry — what it has is a preview image and
the finding written out in words, which is what a screen reader and a search
engine get too. Pressing the button is the only thing that spends a reader’s
bandwidth, and it is their decision.</p>
<figure id="sample-map" class="map" aria-labelledby="sample-map-title" data-astro-cid-jgot2lsh> <figcaption class="map-caption" data-astro-cid-jgot2lsh> <strong id="sample-map-title" class="map-title" data-astro-cid-jgot2lsh>The interactive shell, with nothing real inside it</strong> <span class="map-subtitle" data-astro-cid-jgot2lsh>A demonstration of the loading contract. The real map arrives with the phone-theft piece.</span> </figcaption> <div class="map-stage" data-map-stage data-module="/scripts/sample-map.js" data-map-id="sample-map" data-astro-cid-jgot2lsh> <img src="/og/design-system-sample.png" alt="A placeholder standing in for an interactive map, which loads only after the reader asks for it." width="1200" height="630" decoding="async" loading="lazy" class="map-preview" data-astro-cid-jgot2lsh> <button type="button" class="map-activate" data-map-activate aria-describedby="sample-map-title" data-astro-cid-jgot2lsh> Load the demonstration </button> </div> <div class="map-alternative" data-astro-cid-jgot2lsh> <h3 class="map-alternative-title" data-astro-cid-jgot2lsh>What this map shows</h3> <ul><li>Nothing here is a map of anything: the module draws a panel saying so.</li><li>The contract it proves is the one that matters — zero bytes of map code
until a click, and a readable alternative for everyone who never clicks.</li></ul> </div> </figure>  <script>
	document.querySelectorAll('[data-map-stage]').forEach((stage) => {
		const button = stage.querySelector('[data-map-activate]');
		if (!button) return;
		button.addEventListener(
			'click',
			async () => {
				button.disabled = true;
				button.textContent = 'Loading…';
				try {
					const module = await import(stage.dataset.module);
					await module.default(stage);
					stage.dataset.mapLoaded = 'true';
				} catch (error) {
					button.disabled = false;
					button.textContent = 'The map failed to load. Try again?';
					console.error('map: activation failed', error);
				}
			},
			{ once: false },
		);
	});
</script> 
<span class="claim" data-astro-cid-sbzmajdw> <p>Loading a map on intent will cost less reader patience than loading one
automatically, even though it takes an extra tap.</p> <a class="claim-badge claim-hypothesis" href="/methods/#hypothesis" title="What &#34;Hypothesis&#34; means here" data-astro-cid-sbzmajdw> Hypothesis </a> <span class="claim-test" data-astro-cid-sbzmajdw>Test: Whether the phone-theft map in WP-06 loads inside two seconds on a mid-range Android over a real mobile connection.</span> </span> 
<section id="behind-the-data" class="behind" aria-labelledby="behind-the-data-title" data-astro-cid-ckyjylov> <h2 id="behind-the-data-title" class="behind-title" data-astro-cid-ckyjylov>Behind the data</h2> <div class="behind-prose" data-astro-cid-ckyjylov> <p><strong>Method.</strong> Two files are generated by a formula in <code>fetch.py</code> — three offset
sine curves for the first figure, one for the second — written to
<code>data-cache/</code>, checksummed into the manifest, and turned into JSON by
<code>transform.py</code>. Running the pipeline twice produces byte-identical output,
which is the property that makes <code>just data &lt;slug&gt;</code> a check rather than a
hope.</p><p><strong>Caveats.</strong> There is only one, and it is the whole point: none of these
numbers measures anything. The borough names are labels, not subjects. Do not
quote a single figure from this page.</p><p><strong>What would change my mind.</strong> Nothing about London — there is no claim here
to overturn. What would change the <em>design</em>: a real piece whose figures need
something this shell cannot express, which is exactly what the first three
pieces are for.</p> </div> <div class="behind-apparatus" data-astro-cid-ckyjylov> <h3 class="behind-subtitle" data-astro-cid-ckyjylov>Sources</h3> <ul class="behind-sources" data-astro-cid-ckyjylov> <li data-astro-cid-ckyjylov> <a href="https://github.com/sluvec/londology.co.uk" rel="noopener" data-astro-cid-ckyjylov>Synthetic borough readings</a> — Londology.
<span class="behind-licence" data-astro-cid-ckyjylov>CC0-1.0</span>. Retrieved  <time datetime="2026-08-16" data-astro-cid-ckyjylov>16 August 2026</time>.
<span class="behind-note" data-astro-cid-ckyjylov>Not a measurement of anything. Generated by fetch.py from a fixed formula so that a re-run produces the same checksum, and named after real boroughs only so the chart has plausible labels.</span> </li><li data-astro-cid-ckyjylov> <a href="https://github.com/sluvec/londology.co.uk" rel="noopener" data-astro-cid-ckyjylov>Synthetic river gauge series</a> — Londology.
<span class="behind-licence" data-astro-cid-ckyjylov>CC-BY-4.0</span>. Retrieved  <time datetime="2026-08-16" data-astro-cid-ckyjylov>16 August 2026</time>.
<span class="behind-note" data-astro-cid-ckyjylov>The second licence is the point: it proves the attribution stack keeps two differently licensed sources apart instead of merging them into one line.</span> </li> </ul>  <h3 class="behind-subtitle" data-astro-cid-ckyjylov>Attribution</h3> <ul class="behind-attribution" data-astro-cid-ckyjylov> <li data-astro-cid-ckyjylov> <span class="behind-licence" data-astro-cid-ckyjylov>CC0-1.0</span> <span class="behind-for" data-astro-cid-ckyjylov> Synthetic borough readings </span> <q class="behind-string" data-astro-cid-ckyjylov>Synthetic sample data by Londology, dedicated to the public domain under CC0 1.0.</q> </li><li data-astro-cid-ckyjylov> <span class="behind-licence" data-astro-cid-ckyjylov>CC-BY-4.0</span> <span class="behind-for" data-astro-cid-ckyjylov> Synthetic river gauge series </span> <q class="behind-string" data-astro-cid-ckyjylov>Synthetic sample series by Londology, licensed under CC BY 4.0.</q> </li> </ul> <p class="behind-asof" data-astro-cid-ckyjylov>
Data as of  <time datetime="2026-08-16" data-astro-cid-ckyjylov>16 August 2026</time>. Last
			fetched <time datetime="2026-08-16" data-astro-cid-ckyjylov>16 August 2026</time>.
			Pipeline code is available on request.
</p> </div> </section> ]]></content:encoded>
    </item>
  </channel>
</rss>
