/* GB Grid & Battery Live */

:root {
  /* A quiet grey ground with white blocks on it. The blocks are how a reader
     tells one thing from another: taking them away made the page a single
     column of undifferentiated content, which was clearer to nobody. They are
     defined by a hairline and a small radius, not by a shadow -- the drop
     shadow is what made the old ones look stuck on. */
  --bg: #f4f5f6;
  --panel: #ffffff;
  --panel-2: #f8f9fa;
  --ink: #14171a;
  --ink-2: #4a5158;
  /* 5.2:1 on white and 4.7:1 on the grey ground. The first value tried was
     #767f88, which measured 4.07:1 -- under the 4.5:1 small text needs, and
     this token carries the stat labels and every note on the page. */
  --ink-3: #666e77;
  --line: #e3e6e9;
  --line-2: #ccd2d8;
  /* Deep indigo. It has to sit outside the fuel palette, where the greens,
     blues and teals are all spoken for by generation sources. */
  --accent: #2f3aa3;
  --shadow: none;
  /* Text printed on top of a fuel colour. The fuels are dark and saturated in
     this theme and pastel in the dark one, so this flips the opposite way to
     everything else in the palette: white here, near-black there. */
  --on-fuel: #ffffff;
  /* The slice for electricity used in Britain. It follows the same rule as
     the fuel colours, and originally did not: dark and saturated in this
     theme, pastel in the dark one, because --on-fuel prints white on the
     first and near-black on the second. Set the other way round -- pale here,
     deep there -- the share printed on it was unreadable in BOTH themes: the
     old pair measured 1.7:1 and 3.1:1 against their text. These measure
     5.1:1 and 9.0:1, which the 9px share label needs. Checked, not eyeballed;
     the first value tried here looked right and came out at 4.1:1. */
  --accent-soft: #37796a;

  --gas: #c1651f;
  --coal: #4a403a;
  --oil: #8b5a34;
  --wind: #1a6ea8;
  --solar: #d3a006;
  --hydro: #0c8e87;
  --nuclear: #6b4cb8;
  --biomass: #5b8f2e;
  --other: #8a857e;
  --imports: #a83c78;
  --pumped: #5aa9e6;
  --discharge: #0f9160;
  --charge: #c2325c;
  --price: #6a58c0;
  --forecast: #a99ee0;

  --land: #e2ded2;
  --land-line: #a9a294;
  --abroad: #f1efe9;
  --abroad-line: #c8c1b3;
  --very-low: #197a4e;
  --low: #3f8c3b;
  --moderate: #c99a2e;
  --high: #cf7038;
  --very-high: #bf4340;
}


* { box-sizing: border-box; }

html { -webkit-text-size-adjust: 100%; }

body {
  margin: 0;
  background: var(--bg);
  color: var(--ink);
  font: 15.5px/1.6 var(--sans);
  font-variant-numeric: tabular-nums;
  overflow-x: hidden;
}

/* One stack, and it is a sans. The serif experiment set the headline figures
   in Palatino, whose numerals are old-style -- 3, 4, 7 and 9 hang below the
   line and 6 and 8 rise above it. That is right in a paragraph and wrong in a
   column of figures meant to be compared at a glance, which is most of this
   page. Lining tabular numerals, always.

   System fonts only. A webfont would be a third-party request on a page whose
   whole argument is that it fronts its own data. */
:root {
  --sans: ui-sans-serif, system-ui, -apple-system, "Segoe UI", Roboto,
          "Helvetica Neue", Arial, sans-serif;
  --mono: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, monospace;
}

.wrap { max-width: 1180px; margin: 0 auto; padding: 0 20px; }

a { color: var(--accent); text-decoration-thickness: 1px; text-underline-offset: 2px; }

.visually-hidden {
  position: absolute; width: 1px; height: 1px; overflow: hidden;
  clip: rect(0 0 0 0); clip-path: inset(50%); white-space: nowrap;
}

/* ---------- top bar ---------- */

.topbar {
  border-bottom: 1px solid var(--line);
  background: var(--panel);
  position: sticky; top: 0; z-index: 20;
}
.topbar .wrap {
  display: flex; align-items: center; justify-content: space-between;
  gap: 16px; min-height: 62px; flex-wrap: wrap;
}
.topbar h1 {
  font: 680 19px/1 var(--sans);
  margin: 0; letter-spacing: -.021em; color: var(--ink);
}
.topbar h1 span {
  font: 500 13.5px/1 var(--sans);
  color: var(--ink-3); letter-spacing: 0; margin-left: 2px;
}
.topbar-right { display: flex; align-items: center; gap: 14px; }
.freshness { margin: 0; font-size: 13px; color: var(--ink-2); }
.freshness.stale { color: var(--high); }

button.ghost {
  font: inherit; font-size: 13px;
  background: transparent; color: var(--ink-2);
  border: 1px solid var(--line-2); border-radius: 999px;
  padding: 5px 13px; cursor: pointer;
}
button.ghost:hover { color: var(--ink); border-color: var(--ink-3); }

/* ---------- layout ---------- */

main { padding-bottom: 56px; }
section { margin: 40px 0; }
.section-head {
  display: flex; align-items: baseline; justify-content: space-between;
  gap: 16px; flex-wrap: wrap; margin-bottom: 16px;
}
/* Sentence case, dark, and large enough to be the obvious start of a section.
   The old uppercase letterspaced grey was a label pretending to be a heading:
   it read as furniture, so nothing on the page announced where one part
   stopped and the next began. */
h2 {
  font: 680 21px/1.25 var(--sans);
  letter-spacing: -.02em; color: var(--ink); margin: 0;
  text-transform: none;
}
h3 { font: 650 15px/1.3 var(--sans); margin: 0 0 12px; letter-spacing: -.01em; color: var(--ink); }

/* A white block on a grey ground, held by a hairline and a small radius. No
   shadow: the shadow is what made these look pasted on rather than part of
   the page. */
.card {
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: 6px;
  padding: 18px 20px;
  box-shadow: none;
}
.card + .card { margin-top: 16px; }

.note { font-size: 12.5px; color: var(--ink-3); margin: 6px 0 0; }
.card > .note:first-of-type { margin-bottom: 14px; }
.lede { font-size: 17px; line-height: 1.45; margin: 0 0 18px; max-width: 62ch; }
.lede strong { font-weight: 650; }
.lede.warn { color: var(--high); font-size: 15px; }

/* ---------- headline stats ---------- */

.stats {
  display: grid;
  /* auto-fit rather than a fixed five, so a wrapped row fills the width
     instead of leaving a hole where the sixth column would be */
  grid-template-columns: repeat(auto-fit, minmax(184px, 1fr));
  gap: 12px;
}
.stat {
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: 6px;
  padding: 13px 15px 12px;
  box-shadow: none;
}
.stat dl { margin: 0; }
.stat dt {
  font-size: 12.5px; text-transform: none; letter-spacing: 0;
  color: var(--ink-3); font-weight: 550;
}
.stat dd {
  margin: 4px 0 0; font: 660 31px/1.1 var(--sans); letter-spacing: -.028em;
  font-variant-numeric: tabular-nums lining-nums;
}
.stat dd abbr { font-size: 14px; font-weight: 500; color: var(--ink-3); margin-left: 3px; text-decoration: none; }
.stat dd abbr.pre { margin: 0 1px 0 0; }
.stat[data-key="carbon"] dd .v.very-low { color: var(--very-low); }
.stat[data-key="carbon"] dd .v.low { color: var(--low); }
.stat[data-key="carbon"] dd .v.moderate { color: var(--moderate); }
.stat[data-key="carbon"] dd .v.high { color: var(--high); }
.stat[data-key="carbon"] dd .v.very-high { color: var(--very-high); }

/* ---------- battery ---------- */

.feature > .section-head { border-bottom: 2px solid var(--accent); padding-bottom: 10px; }

/* Wrapping matters here: .section-head wraps, but this did not, so the row
   simply overran its card on a phone. The Europe map's controls are a select
   and three switches -- 449px of them inside a 309px card at 375px wide. */
.controls { display: flex; flex-wrap: wrap; gap: 10px 16px; align-items: center; }
.switch { display: inline-flex; align-items: center; gap: 8px; font-size: 13px; color: var(--ink-2); cursor: pointer; }
.switch input { accent-color: var(--accent); width: 16px; height: 16px; }

.battery-grid > *, .mix-card > *, .stats > * { min-width: 0; }

.battery-grid {
  display: grid;
  grid-template-columns: minmax(240px, 1fr) minmax(0, 2fr);
  gap: 18px;
  align-items: start;
}
.battery-now { grid-row: span 1; }
.battery-chart { grid-column: 2; grid-row: 1 / span 2; }
.battery-arb { grid-column: 1; }
.battery-units { grid-column: 1 / -1; }

.big {
  margin: 4px 0 0; font-size: 46px; font-weight: 650; letter-spacing: -.03em; line-height: 1;
}
.big abbr { font-size: 17px; font-weight: 500; color: var(--ink-3); margin-left: 4px; text-decoration: none; }
.big-label { margin: 6px 0 16px; font-size: 14px; font-weight: 600; letter-spacing: .02em; }
.big-label.discharging { color: var(--discharge); }
.big-label.charging { color: var(--charge); }
.big-label.idle { color: var(--ink-3); }

dl.kv { margin: 0; display: grid; grid-template-columns: 1fr auto; gap: 7px 12px; font-size: 13.5px; }
dl.kv dt { color: var(--ink-2); }
dl.kv dd { margin: 0; text-align: right; font-weight: 600; }
dl.kv dd.emph { color: var(--accent); }
dl.wide { font-size: 14px; gap: 9px 12px; }

.meter { margin-top: 16px; }
.meter-track { height: 7px; background: var(--panel-2); border: 1px solid var(--line); border-radius: 99px; overflow: hidden; }
.meter-fill { height: 100%; width: 0; background: var(--discharge); transition: width .5s ease, background-color .3s; }
.meter-fill.charging { background: var(--charge); }

.spreadbar { margin-top: 14px; display: flex; flex-direction: column; gap: 8px; }
.spread-row { display: flex; align-items: center; gap: 10px; font-size: 12px; color: var(--ink-2); }
.spread-label { flex: none; width: 30px; }
.spread-track {
  flex: 1 1 auto; min-width: 0; height: 13px; border-radius: 99px;
  background: var(--panel-2); overflow: hidden;
}
.spread-fill { display: block; height: 100%; border-radius: 99px; }
.spread-value { flex: none; min-width: 34px; font-variant-numeric: tabular-nums; }

.method {
  margin: 20px 0 0; font-size: 13px; color: var(--ink-2); max-width: 90ch; line-height: 1.6;
  border-left: 2px solid var(--line-2); padding-left: 14px;
}

/* ---------- mix ---------- */

/* The pie and its own breakdown are one object, so they are one card. They
   were two, which put the donut alone in a short box with the table it
   describes starting 18px to the right and running 400px further down; the
   reader had to carry a colour across a gap to use either. The donut column
   is centred against the table's full height rather than pinned to its top. */
.mix-card {
  display: grid;
  /* two rings and the table they share. The rings are the same size on
     purpose: they are two counts of one quantity, and a smaller second one
     would read as a footnote to the first rather than its other half. */
  grid-template-columns: minmax(0, 250px) minmax(0, 250px) minmax(0, 1fr);
  gap: 4px 22px;
  align-items: center;
  padding: 22px 24px;
}
/* Both rings hang from the same top edge rather than being centred against
   the table, so the two pies and the two captions under them line up. Only
   the right one carries a key beneath its caption, and that hangs below
   without dragging the caption out of line with its neighbour. */
.mix-card .pie { margin: 0; align-self: start; }
/* The caption goes above its ring, not under it. These two labels are the
   only thing distinguishing one chart from the other, and set underneath in
   grey letterspaced caps they read as a footnote to a picture the reader has
   already tried to interpret. */
.mix-card .pie { display: flex; flex-direction: column; }
.mix-card .pie figcaption {
  order: -1;
  margin: 0 0 6px; text-align: center;
  font: 650 13.5px/1.3 var(--sans); letter-spacing: -.01em; color: var(--ink);
  text-transform: none;
}
.mix-card .donut { display: flex; align-items: center; justify-content: center; }
.donut svg { width: 100%; max-width: 280px; height: auto; display: block; }

table.sources { width: 100%; border-collapse: collapse; font-size: 13.5px; }
table.sources th, table.sources td { padding: 5px 8px; text-align: right; }
table.sources th:nth-child(2), table.sources td:nth-child(2) { text-align: left; width: 100%; }
table.sources thead th {
  font-size: 11.5px; text-transform: uppercase; letter-spacing: .07em;
  color: var(--ink-2); border-bottom: 1px solid var(--line-2); padding-top: 14px;
}
table.sources tbody td { border-bottom: 1px solid var(--line); color: var(--ink); }
table.sources tbody tr:last-child td { border-bottom: 0; }
table.sources .swatch { width: 18px; padding-right: 0; }
table.sources .swatch .fuel-icon { display: block; width: 16px; height: 16px; }
table.sources td.neg { color: var(--charge); }
table.sources .rownote { color: var(--ink-3); font-size: 11.5px; margin-left: 7px; }
table.sources .bar { width: 96px; min-width: 96px; padding: 5px 0 5px 10px; }
/* A table will not shrink below its min-content width, so when its column is
   narrower it overflows rather than wraps. Contain that here rather than let
   it out through the card border. */
.mix-card .sources-card { overflow-x: auto; }
table.sources .bar div { height: 6px; border-radius: 99px; background: var(--other); min-width: 1px; }

/* ---------- charts ---------- */

.chart { min-width: 0; }
.chart svg { width: 100%; max-width: 100%; height: auto; display: block; overflow: visible; }
.chart .axis text { font-size: 10.5px; fill: var(--ink-3); }
.chart .axis line { stroke: var(--line); stroke-width: 1; }
.chart .zero { stroke: var(--line-2); stroke-width: 1; }
.chart .hit { fill: transparent; cursor: crosshair; }
.chart .hit:hover { fill: var(--ink); fill-opacity: .05; }

.legend { display: flex; flex-wrap: wrap; gap: 6px 16px; font-size: 12.5px; color: var(--ink-2); margin: 12px 0 0; }
.legend .key { display: inline-block; width: 10px; height: 10px; border-radius: 3px; margin-right: 5px; vertical-align: -1px; background: var(--other); }
.legend .key.discharge { background: var(--discharge); }
.legend .key.charge { background: var(--charge); }
.legend .key.line.dashed { background: none; background-image: repeating-linear-gradient(to right, var(--imports) 0 4px, transparent 4px 7px); }
.legend .key.line { height: 3px; border-radius: 2px; width: 14px; vertical-align: 3px; }
.legend .key.price-line { background: var(--price); height: 3px; border-radius: 2px; width: 14px; vertical-align: 3px; }
.legend .key.actual { background: var(--accent); }
.legend .key.forecast { background: var(--forecast); }

.callout {
  margin: 14px 0 0; padding: 11px 14px; border-radius: 10px;
  background: var(--panel-2); border: 1px solid var(--line);
  font-size: 14px; color: var(--ink);
}

details { margin-top: 14px; }
details summary { font-size: 13px; color: var(--ink-2); cursor: pointer; }
details summary:hover { color: var(--ink); }

.table-scroll { overflow-x: auto; margin-top: 10px; }
table.data { width: 100%; border-collapse: collapse; font-size: 13px; }
table.data th, table.data td { padding: 6px 10px; text-align: right; white-space: nowrap; }
table.data th:first-child, table.data td:first-child { text-align: left; }
table.data thead th {
  font-size: 11.5px; text-transform: uppercase; letter-spacing: .06em;
  color: var(--ink-2); border-bottom: 1px solid var(--line-2);
}
table.data tbody td { border-bottom: 1px solid var(--line); }
table.data tbody tr:last-child td { border-bottom: 0; }
table.data td.pos { color: var(--discharge); font-weight: 600; }
table.data td.neg { color: var(--charge); font-weight: 600; }
table.data td.dim { color: var(--ink-3); }
table.data .tag {
  font-size: 10.5px; text-transform: uppercase; letter-spacing: .05em;
  border: 1px solid var(--line-2); border-radius: 99px; padding: 1px 7px; color: var(--ink-3);
}

.prose { max-width: 76ch; }
.prose h3 { margin-top: 22px; }
.prose h3:first-child { margin-top: 0; }
.prose p { font-size: 14.5px; color: var(--ink-2); line-height: 1.62; }

footer { padding: 26px 20px 40px; border-top: 1px solid var(--line); font-size: 13px; color: var(--ink-3); }
footer p { margin: 0 0 4px; }

/* ---------- tooltip ---------- */

#tooltip {
  position: fixed; z-index: 50; pointer-events: none; opacity: 0;
  background: var(--ink); color: var(--bg);
  border-radius: 8px; padding: 8px 11px; font-size: 12.5px; line-height: 1.45;
  max-width: 260px; transition: opacity .12s;
  box-shadow: 0 6px 20px rgba(0,0,0,.25);
}
#tooltip.on { opacity: 1; }
#tooltip b { font-weight: 650; }
#tooltip .row { display: flex; justify-content: space-between; gap: 14px; }
#tooltip .row.tipmore { color: var(--bg); opacity: .6; margin-top: 4px; font-size: 11.5px; }
#tooltip .tipbar {
  display: flex; height: 6px; border-radius: 3px; overflow: hidden;
  margin: 6px 0 7px; background: rgba(127,127,127,.35);
}
#tooltip .tipbar span { display: block; height: 100%; }

/* ---------- responsive ---------- */

/* The three-column mix is two 250px rings plus the table they share, and that
   table cannot go below 397px: 31px of swatch, 147px for "Interconnectors",
   64px and 59px of figures and a 96px bar. So the card needs 989px of content
   box, which is a 1071px viewport -- not the 940px this used to share with
   everything else. Between those two widths the table kept its 397px, ran out
   through the right-hand border of the card and took the page sideways with
   it. The rings pair on one row from here down and the table sits under them
   at full width. */
@media (max-width: 1100px) {
  .mix-card { grid-template-columns: repeat(2, 1fr); gap: 16px 22px; }
  .mix-card .sources-card { grid-column: 1 / -1; }
}

@media (max-width: 940px) {
  .stats { grid-template-columns: repeat(3, 1fr); }
  .battery-grid { grid-template-columns: 1fr; }
  .battery-chart, .battery-arb, .battery-units { grid-column: 1; grid-row: auto; }
  .donut svg { max-width: 240px; }
}

@media (max-width: 560px) {
  .wrap { padding: 0 14px; }
  .stats { grid-template-columns: repeat(2, 1fr); gap: 10px; }
  .stats > :last-child:nth-child(odd) { grid-column: span 2; }
  .stat dd { font-size: 25px; }
  .big { font-size: 38px; }
  .topbar h1 { font-size: 17px; }
  .topbar h1 span { display: none; }
  /* the proportion bars are the first thing to go when width is scarce */
  table.sources .bar, table.sources thead th:last-child { display: none; }
  /* Even without the bars the table is a few pixels wider than a 375px card,
     and a table cannot wrap its way out of that. Eight pixels of cell padding
     either side of five columns is 80px of the 299px available; five is
     enough to keep the figures apart. */
  table.sources th, table.sources td { padding: 5px 5px; }
}

@media (prefers-reduced-motion: reduce) {
  * { transition: none !important; }
}


/* ---------- every site ---------- */

.field select, .field input {
  font: inherit; font-size: 13px;
  background: var(--panel); color: var(--ink);
  border: 1px solid var(--line-2); border-radius: 8px;
  padding: 5px 10px; max-width: 210px;
}
.field input { min-width: 190px; }
.field select:focus-visible, .field input:focus-visible,
.chip:focus-visible, .site-row:focus-visible {
  outline: 2px solid var(--accent); outline-offset: 1px;
}

.fuel-strip { display: flex; flex-wrap: wrap; gap: 8px; margin-bottom: 16px; }
.chip {
  display: flex; align-items: baseline; gap: 7px;
  font: inherit; font-size: 12.5px; cursor: pointer;
  background: var(--panel-2); color: var(--ink);
  border: 1px solid var(--line); border-radius: 99px; padding: 5px 12px;
}
.chip:hover { border-color: var(--ink-3); }
.chip.on { border-color: var(--accent); background: var(--panel); box-shadow: inset 0 0 0 1px var(--accent); }
.chip-label { font-weight: 600; }
.chip-value { font-variant-numeric: tabular-nums; }
.chip-note { color: var(--ink-3); font-size: 11.5px; }

.dot { display: inline-block; width: 9px; height: 9px; border-radius: 3px; margin-right: 7px; vertical-align: 0; }

table.sites td:first-child { white-space: nowrap; font-weight: 500; }
table.sites .bar { width: 90px; min-width: 90px; padding: 6px 0 6px 10px; }
table.sites .bar div { height: 6px; border-radius: 99px; min-width: 1px; }
tr.site-row { cursor: pointer; }
tr.site-row:hover td { background: var(--panel-2); }
tr.site-detail td { padding: 14px 10px 6px; background: var(--panel-2); }
.trace svg { width: 100%; height: auto; display: block; }


/* ---------- map ---------- */

.map { width: 100%; max-width: 780px; }
.map svg { width: 100%; height: auto; }
.land path {
  fill: var(--land);
  stroke: var(--land-line);
  stroke-width: 0.4;
  stroke-linejoin: round;
}
.abroad path {
  fill: var(--abroad);
  stroke: var(--abroad-line);
  stroke-width: 0.4;
  stroke-linejoin: round;
}
.abroad text.country {
  fill: var(--ink-3);
  letter-spacing: .06em;
  text-transform: uppercase;
  pointer-events: none;
}
.site-mark { cursor: pointer; transition: fill-opacity .15s; }
.site-mark:hover { fill-opacity: 1; stroke: var(--ink); stroke-width: 1.2; stroke-opacity: 1; }
.link-hit {
  stroke: transparent;
  stroke-linecap: round;
  pointer-events: stroke;
  cursor: pointer;
}
.cable-halo { opacity: 0; transition: opacity .15s; pointer-events: none; }
.cable { pointer-events: none; }
.link-end { cursor: pointer; }
.link:hover .cable-halo { opacity: 0.22; }
.link:hover .cable { stroke-opacity: 1; }


.prose ul.licences { margin: 10px 0 0; padding-left: 18px; }
.prose ul.licences li {
  font-size: 13.5px; color: var(--ink-2); line-height: 1.55; margin-bottom: 8px;
}
.prose ul.licences code { font-size: 12.5px; color: var(--ink); }

/* ---------- the neighbours ---------- */

.country-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(210px, 1fr));
  gap: 14px;
}
.card.country { padding: 16px; }
.card.country.home { border-color: var(--accent); }
.card.country h3 { display: flex; align-items: center; gap: 8px; margin-bottom: 10px; }
.card.country .flag { font-size: 17px; line-height: 1; }
.country-figure {
  margin: 0; font-size: 28px; font-weight: 650; letter-spacing: -.02em; line-height: 1.1;
}
.country-figure abbr { font-size: 13px; font-weight: 500; color: var(--ink-3); margin-left: 4px; text-decoration: none; }
.mixbar {
  display: flex; height: 8px; border-radius: 99px; overflow: hidden;
  background: var(--panel-2); margin: 14px 0 10px;
}
.mixbar span { display: block; height: 100%; }
.mixlegend { display: flex; flex-wrap: wrap; gap: 4px 12px; margin: 0; font-size: 12px; color: var(--ink-2); }
.mixkey { white-space: nowrap; }
.note.unreachable { color: var(--high); }


/* ---------- Europe map ---------- */

.europe-card { margin-top: 18px; }
.europe-map { width: 100%; max-width: 560px; margin: 0 auto; }
/* Borders carry the map. At 0.4px against a pale fill they were a suggestion,
   and a country's shape is the thing a reader identifies it by. */
.eu-countries path { stroke: var(--land-line); stroke-width: 0.9; stroke-linejoin: round; }
.eu-country { cursor: pointer; }
.eu-country:hover path { stroke: var(--ink); stroke-width: 1.5; }
.eu-country.home path { stroke: var(--ink-2); stroke-width: 0.8; }
.eu-country.pickable { cursor: pointer; }
.eu-country.pickable:focus-visible { outline: none; }
.eu-country.pickable:focus-visible path { stroke: var(--accent); stroke-width: 1.4; }
.eu-country.picked path { stroke: var(--ink); stroke-width: 1.4; }

/* Zooming into a country. The whole stage is one transformable group so the
   flight between two frames costs a transform and not a redraw; the geometry
   is already drawn at the frame it is flying to. */
.eu-zoom { transform-box: view-box; transform-origin: 0 0; }
/* A faded neighbour keeps its outline: dimming the fill says "not this one",
   dimming the border as well takes the country away entirely. */
.eu-country.faded path { fill-opacity: .14 !important; stroke-opacity: .85; }
.eu-country.faded:hover path { fill-opacity: .38 !important; }
.eu-country.focused path { stroke: var(--ink); stroke-width: 1.6; }
.eu-backdrop { cursor: zoom-out; }
.eu-border-flow { fill: none; }
.eu-flows.focused .eu-flow { stroke-opacity: .95; }
.eu-flows.focused .eu-flow-head { fill-opacity: .95; }
.eu-flow-hit { cursor: pointer; }
.eu-flow-hit:hover ~ .eu-border-flow { stroke-opacity: 1; }
/* Fuel icons. One shape per source, in that source's colour, so the legends
   and tables do not rely on colour alone -- which also makes them readable to
   anyone who cannot separate two of these hues. */
.fuel-icon { width: 15px; height: 15px; flex: 0 0 auto; vertical-align: -3px; }
.legend .fuel-icon { margin-right: 5px; }
#tooltip .fuel-icon { width: 13px; height: 13px; vertical-align: -2px; margin-right: 5px; }
table.data td .fuel-icon, table.sources td .fuel-icon { margin-right: 7px; }

.donut-wedge { transition: opacity .12s; cursor: default; }
.donut-wedge:hover { opacity: .82; }
.donut-leader {
  fill: none; stroke: var(--imports); stroke-width: 1; stroke-opacity: .6;
  stroke-linejoin: round; stroke-linecap: round;
}
.donut-code {
  font-size: 10.5px; font-weight: 700; letter-spacing: .02em; fill: var(--imports);
  paint-order: stroke; stroke: var(--panel); stroke-width: 2.5px; stroke-linejoin: round;
}

.eu-flow-label {
  fill: var(--ink-2); font-size: 11px; font-weight: 600;
  paint-order: stroke; stroke: var(--bg); stroke-width: 3px; stroke-linejoin: round;
}

.eu-detail { margin-top: 14px; }
.eu-detail table.data { margin-top: 10px; }
.eu-subhead { margin: 18px 0 0; font-size: 13px; text-transform: uppercase;
  letter-spacing: .06em; color: var(--ink-2); }
.eu-figures { display: flex; flex-wrap: wrap; gap: 10px 26px; margin: 12px 0 14px; }
.eu-figure { display: flex; flex-direction: column; }
.eu-figure-value { font-size: 22px; font-weight: 600; }
.eu-figure-label { font-size: 12px; color: var(--ink-2); }
.chip.go { display: inline-block; margin-top: 6px; text-decoration: none; }

.eu-flow { stroke: var(--ink); stroke-opacity: 0.45; stroke-linecap: round; fill: none; }
.eu-flow.disputed { stroke-dasharray: 3 3; stroke-opacity: 0.35; }
.eu-flow-head { fill: var(--ink); fill-opacity: 0.7; }
.eu-flow-hit { stroke: transparent; fill: transparent; cursor: pointer; }
.eu-flow-hit:hover + .eu-flow, .eu-flows g:hover .eu-flow { stroke-opacity: 0.9; }
#europe-legend { justify-content: center; }
#europe-note { text-align: center; max-width: 66ch; margin-left: auto; margin-right: auto; }


/* ---------- France map ---------- */

.section-head.compact { margin-bottom: 12px; }
.section-head.compact h3 { margin: 0; }
.fr-regions path { stroke: var(--land-line); stroke-width: 0.4; stroke-linejoin: round; }
.fr-region { cursor: pointer; }
.fr-region:hover path { stroke: var(--ink); stroke-width: 1; }
.fr-sites circle { cursor: pointer; transition: fill-opacity .15s; }
.fr-sites circle:hover { fill-opacity: 1; stroke: var(--ink); stroke-width: 1.2; }

@media (max-width: 820px) {
}

/* The supergrid. Flat, thin and behind everything: it is the one layer on the
   map carrying no reading, so it must read as the surface the live marks sit
   on rather than as a mark of its own. Not interactive -- there is nothing to
   say about a circuit beyond where it runs. */
.grid-lines { pointer-events: none; fill: none; }
.grid-lines path { stroke-linecap: round; stroke-linejoin: round; }
/* Weighted by eye against the live station dots, not by a scale. Both bands
   were first set from the old 780 px British map and were invisible here:
   inside the Europe map's 560-unit viewBox Britain is a couple of hundred
   units across, and half a unit of grey on a dark ground is nothing. */
.grid-lines .low  { stroke: var(--ink-3); stroke-width: 0.6;  stroke-opacity: 0.5; }
.grid-lines .high { stroke: var(--ink-2); stroke-width: 0.85; stroke-opacity: 0.55; }

/* The share printed on a donut wedge. Sits in the ring band on top of the
   fuel colour, so it takes --on-fuel rather than any ink. Not a pointer
   target: the wedge underneath it is, and a label swallowing the hover would
   hide the figure it is summarising. */
.donut-share {
  font-size: 9px;
  font-weight: 620;
  fill: var(--on-fuel);
  pointer-events: none;
  font-variant-numeric: tabular-nums;
}

/* Substations: where the supergrid actually joins. Squares, because a circle
   on this map is a power station sized by capacity and a junction is not a
   small one. These do answer a hover -- a substation has a name and a rating,
   where a circuit has neither. */
.grid-nodes rect { stroke: none; cursor: help; }
.grid-nodes .low  { fill: var(--ink-3); fill-opacity: 0.55; }
.grid-nodes .high { fill: var(--ink-2); fill-opacity: 0.7; }
.grid-nodes rect:hover { fill: var(--accent); fill-opacity: 1; }

/* Gas against price. A statistic, not a reading, so it takes the accent
   rather than a fuel colour -- nothing on this chart is "gas-coloured"
   generation. */
.gasprice-line { stroke: var(--accent); stroke-width: 2; stroke-linejoin: round; stroke-linecap: round; }
.gasprice-dot { fill: var(--accent); stroke: var(--panel); stroke-width: 1.4; cursor: help; }
.gasprice-dot:hover { r: 5.6; }
/* four figures, not the headline row's five, and they must not inherit a
   five-column grid and leave a hole where the fifth would be */
.gasprice-stats { margin-top: 18px; grid-template-columns: repeat(4, 1fr); }
@media (max-width: 820px) { .gasprice-stats { grid-template-columns: repeat(2, 1fr); } }
.gasprice-stats .stat dd { font-size: 30px; }
.gasprice-stats .note { margin-top: 2px; }
#gasprice-note { max-width: 78ch; line-height: 1.6; }
.axis-title { fill: var(--ink-3); font-size: 11px; }

#going-note { max-width: 78ch; margin-top: 12px; line-height: 1.6; }
/* the key for the right-hand ring, which has no table beside it to name its
   slices the way the mix ring does */
#legend-going { justify-content: center; margin-top: 6px; font-size: 12px; }

/* A button that reads as a link: used where a control sits inside a sentence,
   like "Showing the 12 busiest of 602 units. Show all". */
.linkish {
  background: none; border: 0; padding: 0; font: inherit; cursor: pointer;
  color: var(--accent); text-decoration: underline; text-underline-offset: 2px;
}
.linkish:hover { text-decoration-thickness: 2px; }

/* The method section: ten explainers, open on demand. Expanded they ran to
   3,100 pixels of a page whose reader mostly wants to know what the grid is
   doing; the detail is kept in full and asked for rather than scrolled past. */
.explain { border-top: 1px solid var(--line); padding: 10px 0; }
.explain:first-of-type { border-top: 0; }
.explain > summary {
  cursor: pointer; list-style: none; font-weight: 600; color: var(--ink);
  display: flex; align-items: center; gap: 8px;
}
.explain > summary::-webkit-details-marker { display: none; }
.explain > summary::before {
  content: "+"; color: var(--accent); font-weight: 700; width: 12px;
}
.explain[open] > summary::before { content: "\2212"; }
.explain > summary:hover { color: var(--accent); }
.explain > *:not(summary) { font-size: 14.5px; color: var(--ink-2); }
