:root {
  --bg:            #070d18;
  --panel:         #0f1a2d;
  --panel-2:       #132340;
  --line:          #1e3355;
  --line-soft:     #17293f;
  --ink:           #e8eefb;
  --ink-dim:       #8ea3c4;
  --ink-faint:     #5c76a0;
  --consum:        #f2994a;
  --productie:     #58c98a;
  --sold:          #4aa8f0;
  --frecventa:     #f5d547;
  --import:        #4aa8f0;
  --export:        #58c98a;
  --idle:          #55688a;
  --land:          #111e31;
  --land-line:     #1d3452;
  --ro-land:       #21406a;
  --ro-line:       #5d95d4;
  --radius:        10px;
}

* { box-sizing: border-box; }

body {
  /* No horizontal scroll, ever. A line that comes out a few pixels too wide on
     a phone makes the browser zoom the entire page out to fit it, and the page
     then looks squeezed into the left half of the screen until it is reloaded.
     Clipping costs those few pixels; the alternative costs the whole layout. */
  overflow-x: clip;
  margin: 0;
  background: radial-gradient(1200px 700px at 50% -10%, #0d1a2e 0%, var(--bg) 60%);
  color: var(--ink);
  font: 400 15px/1.45 system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
  font-variant-numeric: tabular-nums;
  display: flex;
  flex-direction: column;
  min-height: 100vh;
}

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

.topbar {
  display: grid;
  grid-template-columns: 1fr auto 1fr;
  align-items: center;
  gap: 16px;
  padding: 14px 22px;
  border-bottom: 1px solid var(--line-soft);
}

.brand {
  display: flex;
  align-items: center;
  gap: 11px;
  color: var(--ink-dim);
  min-width: 0;
}

/* Sized by height, not by a square box: the mark is wider than it is tall
   (160x128), so a 34px square would have letterboxed it down to 26px of
   actual mark and left the wordmark beside it looking oversized.

   Lifted two pixels because centring its box does not centre the mark. It is
   a triangle with a curl under it, so its weight sits 7-10% below the middle
   of its own bounding box -- measured both by area and by brightness -- and
   flex centring lines up boxes. Without the lift the mark reads as sagging
   next to the two lines of text beside it. */
.brand-mark { height: 30px; width: auto; flex: none; transform: translateY(-2px); }

.brand-text { display: flex; flex-direction: column; line-height: 1.25; min-width: 0; }
.brand-text strong { color: var(--ink); font-size: 15px; font-weight: 600; }
.brand-text span { font-size: 12px; color: var(--ink-faint); }

.page-title {
  margin: 0;
  font-size: 27px;
  font-weight: 700;
  letter-spacing: .2px;
  white-space: nowrap;
  display: flex;
  align-items: center;
  gap: 12px;
}

.live-dot {
  width: 10px; height: 10px;
  border-radius: 50%;
  background: var(--productie);
  box-shadow: 0 0 0 0 rgba(88, 201, 138, .6);
  animation: pulse 2.4s ease-out infinite;
}
.live-dot.is-stale { background: var(--consum); box-shadow: none; animation: none; }
.live-dot.is-down  { background: #e05b5b; box-shadow: none; animation: none; }

@keyframes pulse {
  0%   { box-shadow: 0 0 0 0 rgba(88, 201, 138, .55); }
  70%  { box-shadow: 0 0 0 9px rgba(88, 201, 138, 0); }
  100% { box-shadow: 0 0 0 0 rgba(88, 201, 138, 0); }
}

.topbar-right {
  display: flex;
  align-items: center;
  justify-content: flex-end;
  gap: 18px;
}

.clock { color: var(--ink-dim); font-size: 15px; white-space: nowrap; }

.lang { display: flex; align-items: center; gap: 7px; color: var(--ink-faint); font-size: 13px; }
.lang button {
  background: none; border: 0; padding: 2px 1px;
  color: var(--ink-faint); font: inherit; cursor: pointer; border-radius: 3px;
}
.lang button:hover { color: var(--ink-dim); }
.lang button.is-active { color: var(--sold); font-weight: 600; }
.lang button:focus-visible,
.brand:focus-visible { outline: 2px solid var(--sold); outline-offset: 2px; }

/* ---------- banner ---------- */

.banner {
  margin: 12px 22px -4px;
  padding: 9px 14px;
  border: 1px solid #6b4a1e;
  background: #2a1e0d;
  color: #f0c489;
  border-radius: var(--radius);
  font-size: 13.5px;
}
.banner[hidden] { display: none; }

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

.layout {
  --pad: 22px;
  /* The information band's own row, subtracted below alongside its grid gap
     so the desktop page still lands on exactly one screen -- 285px did not
     account for a row that did not exist yet. */
  --band-h: 46px;
  flex: 1;
  display: grid;
  /* Charts left, map centre, figures right. The charts moved out of a
     full-width row at the bottom because a 24 h line stretched across 1400px
     is hard to follow and pushed everything else below the fold; in a column
     the same window reads at a glance and the page stops scrolling. */
  grid-template-columns: clamp(356px, 27vw, 420px) minmax(0, 1fr) clamp(336px, 25vw, 400px);
  /* Row 3 needs a definite height, not 1fr: the exchange table is 22 rows and
     would otherwise stretch the row until the page scrolled again, which is
     the whole thing this layout exists to avoid. Given a height it scrolls
     inside its own column instead. */
  /* Deriving it from the fixed chrome rather than a vh fraction is what makes
     the page land on exactly one screen at any height: 285px is the top bar,
     the KPI strip, the footer and this grid's own padding, measured. */
  grid-template-rows: auto auto clamp(520px, calc(100vh - 285px - var(--band-h) - 14px), 900px);
  /* Rows are sized deliberately, so leftover height must not be handed back to
     them: the default (stretch) grew the auto row -- the KPI strip -- and left
     a band of dead space under the sparklines that pushed everything down. */
  align-content: start;
  gap: 14px;
  padding: 14px var(--pad) 18px;
}

.kpis { grid-column: 1 / -1; }

.band {
  grid-column: 1 / -1;
  grid-row: 2;
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  gap: 14px;
  background: linear-gradient(180deg, var(--panel) 0%, #0c1727 100%);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: 9px 14px;
}
.band[hidden] { display: none; }

.charts {
  grid-column: 1; grid-row: 3;
  display: flex;
  flex-direction: column;
  gap: 14px;
  min-height: 0;
}

/* The evolution plot carries a frequency strip as well, so it gets the
   larger share of the column. */
.panel--chart { flex: 1.2 1 0; }
.panel--mix   { flex: 1 1 0; }

.panel--map { grid-column: 2; grid-row: 3; }
.side {
  grid-column: 3; grid-row: 3;
  display: flex; flex-direction: column; gap: 14px;
  min-height: 0;
  /* On a short window the exchange table would be squeezed to a couple of
     rows; give it a floor and let the whole column scroll instead. */
  overflow-y: auto;
  scrollbar-width: thin;
  scrollbar-color: #24406a transparent;
}

.side::-webkit-scrollbar { width: 8px; }
.side::-webkit-scrollbar-thumb { background: #24406a; border-radius: 4px; }
.side::-webkit-scrollbar-track { background: transparent; }

.panel {
  background: linear-gradient(180deg, var(--panel) 0%, #0c1727 100%);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  min-width: 0;
}

.panel--flex { flex: 1 0 auto; display: flex; flex-direction: column; min-height: 240px; }

.panel-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 12px;
  padding: 11px 16px;
  border-bottom: 1px solid var(--line-soft);
}
.panel-head h2 { margin: 0; font-size: 16px; font-weight: 600; }

.panel--chart .panel-head, .panel--mix .panel-head { padding: 8px 14px; }
.panel--chart .panel-head h2, .panel--mix .panel-head h2 { font-size: 15px; }
.panel-total { color: var(--productie); white-space: nowrap; }
.panel-total b { font-size: 19px; font-weight: 700; }
.panel-total i { font-style: normal; font-size: 12px; color: var(--ink-faint); margin-left: 2px; }

/* ---------- KPI strip ---------- */

.kpis {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  background: linear-gradient(180deg, var(--panel) 0%, #0c1727 100%);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  overflow: hidden;
}

.kpi {
  padding: 11px 20px;
  border-left: 1px solid var(--line-soft);
  min-width: 0;
}

/* Consumption and generation carry no sparkline: a line with no baseline to
   read it against says nothing on its own -- the chart below does that job
   properly. Their tiles centre what is left rather than leaving the band the
   sparkline used to occupy sitting empty. */
.kpi--plain {
  display: flex;
  flex-direction: column;
  justify-content: center;
}
.kpi:first-child { border-left: 0; }

.kpi-label { display: block; font-size: 14px; font-weight: 600; margin-bottom: 3px; }
.kpi--consum    .kpi-label { color: var(--consum); }
.kpi--productie .kpi-label { color: var(--productie); }
/* White, so that blue is free to mean one thing only on this page: import.
   The direction word underneath carries the colour instead. */
.kpi--sold      .kpi-label { color: var(--ink); }
.kpi--frecventa .kpi-label { color: var(--frecventa); }

.kpi-value { display: flex; align-items: baseline; gap: 6px; white-space: nowrap; }
.kpi-value b { font-size: 31px; font-weight: 700; letter-spacing: -.4px; }
.kpi-value i { font-style: normal; font-size: 16px; color: var(--ink-dim); }
.kpi-value em { font-style: normal; font-size: 12.5px; font-weight: 600; color: var(--ink-faint); }
.kpi-value em.dir--export { color: var(--export); }
.kpi-value em.dir--import { color: var(--import); }

/* The same figure with the rooftop estimate folded in, shown only while the
   estimate is switched on somewhere. Under the headline number rather than
   replacing it: that one is metered, and a total that silently mixes a
   measurement with a model cannot be taken apart again. */
.kpi-extra {
  display: flex;
  align-items: baseline;
  gap: 5px;
  margin-top: 3px;
  font-size: 11.5px;
  color: var(--ink-faint);
  /* Wrapping, not nowrap. The line gained an "i" and the tile is 45% of a
     390px phone: nowrap made it nine pixels too wide, which costs the whole
     page its scale rather than this line its second row. */
  flex-wrap: wrap;
  min-width: 0;
}
.kpi-extra[hidden] { display: none; }
/* The colon rides on the label rather than sitting beside it as its own text
   node: `.kpi-extra` is a flex row with a gap, and a loose ":" would be spaced
   off the word it belongs to. */
.prosum-tag::after { content: ':'; }
.kpi-extra b { font-size: 13.5px; font-weight: 700; color: var(--ink-dim); margin-left: 2px; }
.kpi-extra i { font-style: normal; }

/* A stacked bar under the two plain tiles: what the generation figure is made
   of, and what the consumption figure is covered by. The number above says how
   much; this says of what, without asking the reader to travel to the panel on
   the right.

   Thin on purpose. It is an annotation on a headline number, not a chart --
   anything taller starts competing with the figure it belongs to. */
.mixbar {
  display: flex;
  gap: 2px;
  height: 8px;
  margin-top: 8px;
  border-radius: 4px;
  /* The gap shows the tile through rather than a painted seam, so adjacent
     segments separate without a border darkening either colour. */
  overflow: hidden;
  touch-action: pan-y;
}
.mixbar[hidden] { display: none; }
.mixbar-seg {
  min-width: 2px;
  cursor: pointer;
  transition: opacity .15s ease;
}
/* Reading one segment dims the others rather than highlighting the one, so the
   bar keeps its full width and nothing moves under the pointer. */
.mixbar.is-reading .mixbar-seg { opacity: .32; }
.mixbar.is-reading .mixbar-seg.is-read { opacity: 1; }
/* The rooftop segment is modelled, not metered, and carries the same dashed
   treatment as its swatch in the panel and its band in the chart. */
.mixbar-seg--est {
  background-image: repeating-linear-gradient(
    -45deg, rgba(11, 20, 34, .55) 0 2px, transparent 2px 5px);
}

/* Fixed, not absolute: `.kpis` clips to its own rounded corners, and a tooltip
   hanging below the tile would be cut off at the panel edge. */
.mixbar-tip {
  position: fixed;
  z-index: 40;
  max-width: min(280px, 88vw);
  padding: 7px 10px;
  background: var(--panel-2);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  box-shadow: 0 8px 24px rgba(0, 0, 0, .45);
  font-size: 12px;
  line-height: 1.45;
  color: var(--ink-dim);
  white-space: nowrap;
  pointer-events: none;
}
.mixbar-tip[hidden] { display: none; }
/* `.swatch` carries a width and a height but no display, and it is only ever
   used inside a grid row, which blockifies it. Here the parent is plain text,
   so without this it stays inline and collapses to a sliver. */
.mixbar-tip .swatch { display: inline-block; margin-right: 6px; vertical-align: -1px; }
.mixbar-tip b { color: var(--ink); font-weight: 600; }
.mixbar-tip i { font-style: normal; color: var(--ink-faint); }

.kpi-spark { display: block; position: relative; height: 30px; margin-top: 5px; cursor: crosshair; touch-action: pan-y; }
.kpi-spark svg { display: block; width: 100%; height: 30px; overflow: visible; }
.spark-line { fill: none; stroke-width: 1.6; stroke-linejoin: round; stroke-linecap: round; opacity: .85; }
.spark-gap { stroke-dasharray: 2 3; opacity: .3; }
/* The reference line is the thing the series is read against -- zero for the
   balance, 50 Hz for frequency -- so it has to survive being 30px tall. */
.spark-zero { stroke: rgba(176, 206, 244, .6); stroke-width: 1; stroke-dasharray: 3 3; }
.spark-cross { stroke: rgba(160, 190, 230, .55); stroke-width: 1; }
.spark-hover-dot { stroke: #0b1626; stroke-width: 1.2; }
.spark-tip {
  position: absolute;
  right: 0;
  top: -17px;
  font-size: 11px;
  font-weight: 600;
  white-space: nowrap;
  pointer-events: none;
  background: rgba(9, 18, 32, .9);
  padding: 0 3px;
  border-radius: 3px;
}
.spark-tip[hidden] { display: none; }

/* Frequency against its band. Same height as the sparkline it replaces, so
   the KPI row does not change shape. */
.kpi-band {
  display: flex;
  align-items: center;
  gap: 8px;
  height: 30px;
  margin-top: 5px;
  position: relative;
  cursor: default;
}
.kpi-band[hidden] { display: none; }
.kpi-band em {
  font-style: normal;
  font-size: 10.5px;
  font-weight: 600;
  color: var(--ink-faint);
  white-space: nowrap;
  font-variant-numeric: tabular-nums;
}
.fb-track {
  position: relative;
  flex: 1;
  min-width: 0;
  height: 6px;
  border-radius: 3px;
  background: rgba(125, 165, 215, .14);
}
/* Today's range, behind the marker on the same axis. Without it the tile says
   where the grid is and nothing about where it has been, and on a calm day
   those are two very different reassurances. */
.fb-span {
  position: absolute;
  top: 0;
  height: 100%;
  border-radius: 3px;
  background: rgba(245, 213, 71, .3);
  transition: left .5s ease, width .5s ease;
}
.fb-span[hidden] { display: none; }
.fb-mid, .fb-limit {
  position: absolute;
  top: -2px;
  width: 1px;
  height: 10px;
  transform: translateX(-.5px);
}
.fb-mid { background: rgba(200, 220, 250, .45); }
.fb-limit { background: rgba(125, 165, 215, .3); }
/* The marker outranks everything else in the track, so it is taller than the
   track is thick and carries a glow -- at three pixels wide on a busy tile it
   otherwise reads as one more tick. */
.fb-now {
  position: absolute;
  top: -4px;
  width: 3px;
  height: 14px;
  margin-left: -1.5px;
  border-radius: 2px;
  background: var(--frecventa);
  box-shadow: 0 0 7px rgba(245, 213, 71, .8);
  transition: left .5s ease;
}

.fb-tip {
  position: absolute;
  right: 0;
  bottom: 26px;
  z-index: 3;
  display: flex;
  flex-direction: column;
  gap: 2px;
  padding: 7px 9px;
  background: rgba(9, 18, 32, .96);
  border: 1px solid var(--line);
  border-radius: 7px;
  font-size: 11px;
  font-weight: 600;
  color: var(--ink-dim);
  white-space: nowrap;
  pointer-events: none;
}
.fb-tip[hidden] { display: none; }
.fb-tip b { color: var(--ink); font-weight: 600; }
.fb-tip svg { display: block; width: 132px; height: 34px; }

.kpi--consum    .kpi-value b { color: var(--consum); }
.kpi--productie .kpi-value b { color: var(--productie); }
.kpi--sold      .kpi-value b { color: var(--ink); }
/* The only tile whose number has a sign, so the only one where the direction
   is the story rather than a unit. The wash is faint and fades out downward:
   at a flat tint the tile read as selected, which is a different claim. */
.kpi--sold.is-export { background: linear-gradient(180deg, rgba(88, 201, 138, .1), rgba(88, 201, 138, 0) 72%); }
.kpi--sold.is-import { background: linear-gradient(180deg, rgba(74, 168, 240, .1), rgba(74, 168, 240, 0) 72%); }
.kpi--sold.is-export .kpi-value b { color: var(--export); }
.kpi--sold.is-import .kpi-value b { color: var(--import); }
.kpi--sold .kpi-value em { font-size: 14px; letter-spacing: .01em; }
.kpi--frecventa .kpi-value b { color: var(--frecventa); }

/* ---------- information band ---------- */

.band-slot { min-width: 0; position: relative; }
.band-slot[hidden] { display: none; }

.band-kicker {
  display: flex;
  align-items: center;
  gap: 6px;
  font-size: 11px;
  font-weight: 600;
  letter-spacing: .04em;
  text-transform: uppercase;
  color: var(--ink-faint);
  margin-bottom: 2px;
}

.band-line {
  display: block;
  font-size: 18px;
  font-weight: 700;
  color: var(--ink);
  line-height: 1.3;
}

/* --ink-dim, not --ink-faint. The faint token gives 3.9:1 on the band's own
   gradient, under the 4.5:1 body text needs, and the line read as greyed out
   rather than secondary. The dim token gives 7.0:1 and still sits well below
   the headline above it, which is white at 15.5:1.

   13px, up from 11.5. This line carries the numbers people actually squint at
   -- the day's minimum and maximum price, and the hours they fell on -- and at
   the old size they were the smallest text on the page. Still five below the
   headline, so the hierarchy is unchanged. */
.band-sub {
  display: block;
  margin-top: 2px;
  font-size: 13px;
  color: var(--ink-dim);
}
/* Without this the display:block above outranks the browser's own [hidden]
   rule, so hiding the sub line does nothing and a Romanian bani/kWh figure
   stays on screen underneath a European headline. */
.band-sub[hidden] { display: none; }

/* A market price shown in lei per kilowatt-hour looks exactly like the tariff
   line on a bill, which it is not. The mark is small but reachable, and the
   panel it opens says what the number is before anyone works it out wrongly. */
.band-info {
  flex: none;
  width: 14px;
  height: 14px;
  padding: 0;
  border: 1px solid var(--ink-faint);
  border-radius: 50%;
  background: none;
  color: var(--ink-faint);
  font: 600 10px/1 system-ui, sans-serif;
  font-style: italic;
  cursor: pointer;
  text-transform: none;
  letter-spacing: 0;
}
.band-info:hover, .band-info:focus-visible { color: var(--ink); border-color: var(--ink-dim); }
.band-info:focus-visible { outline: 2px solid var(--import); outline-offset: 2px; }

/* Absolutely positioned so opening it cannot change the band's height and
   shove the charts down -- the whole reason the band is a fixed shelf. */
.band-tip {
  position: absolute;
  z-index: 20;
  top: calc(100% + 6px);
  left: 0;
  max-width: min(420px, 92vw);
  padding: 9px 11px;
  background: var(--panel-2);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  box-shadow: 0 8px 24px rgba(0, 0, 0, .45);
  font-size: 12px;
  line-height: 1.45;
  font-weight: 400;
  color: var(--ink-dim);
  text-transform: none;
  letter-spacing: 0;
}
.band-tip[hidden] { display: none; }
.band-tip b { color: var(--ink); font-weight: 600; }

/* Content rotation, not an animated slide -- the reduced-motion block below
   already turns every transition off, which silently satisfies "no animated
   change, content still changes" without a JS branch. */
.band-line, .band-sub, .band-kicker { transition: opacity .28s ease; }

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

.panel--map { position: relative; display: flex; flex-direction: column; overflow: hidden; }
/* Depth behind the drawing. The panel is one flat tone and the map floated on
   it; a light from above and a heavier floor give the sea somewhere to be, so
   the land reads as sitting on something rather than cut out of it. Both stops
   end fully transparent, so the panel colour is still what shows through and
   nothing here is a second background. */
.map {
  position: relative; flex: 1; min-height: 300px; min-width: 0;
  background:
    radial-gradient(120% 85% at 50% -5%, rgba(43, 74, 119, .34) 0%, rgba(15, 26, 45, 0) 62%),
    radial-gradient(95% 65% at 50% 108%, rgba(6, 13, 26, .5) 0%, rgba(15, 26, 45, 0) 72%);
}
/* The vignette goes over the drawing, not under it, or the gradients above
   would simply cancel it. Weak enough that nothing near the frame is dimmed
   past reading -- the outermost flow captions live there. */
.map::after {
  content: '';
  position: absolute;
  inset: 0;
  pointer-events: none;
  box-shadow: inset 0 0 70px 10px rgba(4, 9, 18, .38);
}
/* Absolute fill keeps the SVG box tied to the panel, never to its own
   intrinsic size -- otherwise the viewBox feeds back into the grid row. */
.map svg { position: absolute; inset: 10px; width: calc(100% - 20px); height: calc(100% - 20px); display: block; }

/* Stroke widths and font sizes below are viewBox units, driven by scaleMapInk()
   so they render at a constant on-screen size whatever the panel width. The
   literals are only the pre-script fallback. */
/* Lighter than --land, for the same reason the European map's uncoloured
   countries were lifted: at the old tone the neighbours sat barely above the
   sea and the map looked like Romania floating in water rather than Romania
   among countries. Still well below the Romanian fill, which has to stay the
   subject. */
.geo-neighbour { fill: #223855; stroke: #2c4870; stroke-width: 1; }
/* The halo used to sit on the whole outline at full strength, which said
   nothing except "Romania" -- and the map already says that. What is left is
   just enough to keep the country off the sea; the frontier lighting below
   carries the signal, one neighbour at a time. */
.geo-ro {
  fill: var(--ro-land);
  stroke: var(--ro-line);
  stroke-width: var(--sw-ro, 1.8);
  filter: drop-shadow(0 0 10px rgba(77, 127, 184, .16));
}

/* The stretch of frontier facing one neighbour, lit by what crosses it:
   colour for the direction, brightness for the size, the same pairing the
   arrows use. Two layers, because a blur on its own reads as fog rather than
   as a lit border, and a sharp line on its own does not glow at all.

   One blur on the group, not a filter per border. Blur in CSS pixels rather
   than an SVG feGaussianBlur in user units, so the halo holds its on-screen
   weight the way the type does -- in viewBox units it would be three times
   heavier on a phone than on a desktop panel. */
#roGlowWide { filter: blur(3.5px); }
.border-glow {
  fill: none;
  stroke-linecap: round;
  stroke-linejoin: round;
  transition: opacity .6s ease, stroke .6s ease;
}
.border-glow--wide { stroke-width: var(--sw-glow, 6); }
.border-glow--core { stroke-width: var(--sw-ro, 1.8); }

/* The rooftop layer's light. One blur on the group: forty-one filtered discs
   is a cost on a phone, and the discs overlap anyway, which is the point --
   two neighbouring counties producing hard should read as one bright region,
   not as two circles. */
/* The day/night boundary over this corner of the continent, when it is here
   at all. Same treatment as the European one, at the Romanian sheet's scale:
   blurred, because dusk is not a line, and warm because it is the one mark on
   this map that is neither a wire nor a flow. */
/* The sun that names the boundary. Crisp on purpose -- everything else in
   this group is blurred, and a blurred icon is a smudge. Dark edged, because
   it crosses a lit country as often as it crosses the sea. */
.sun { pointer-events: none; }
/* The bloom the disc sits in. Without it the sun is pasted onto the map;
   with it, it is a light source on the map. */
.sun-halo {
  fill: rgba(255, 196, 96, .3);
  filter: blur(7px);
}
.sun-rays {
  fill: #ffcf72;
  stroke: rgba(58, 32, 6, .45);
  stroke-width: .5;
  stroke-linejoin: round;
}
.sun-disc {
  stroke: rgba(58, 32, 6, .7);
  stroke-width: .9;
}

#roDusk { pointer-events: none; }
.ro-dusk { fill: none; stroke: rgba(255, 178, 98, .58); stroke-width: var(--sw-dusk, 6); filter: blur(4px); }
/* The same fill the European sheet uses. Lightened a little, not a lot: there
   it lies over land and outlines, here it lies over the county tints the
   rooftop layer paints, and the tint still has to be readable through it at
   dusk -- which is the hour the layer exists to show. Set at .34 first, and
   that was too timid: the boundary is only as visible as the difference across
   it, and against a barely darkened half the line had nothing to divide. */
.ro-nightfill { fill: rgba(2, 4, 10, .44); stroke: none; pointer-events: none; }
.ro-daylight {
  fill: none;
  stroke: rgba(255, 206, 140, .19);
  stroke-width: 30;
  filter: blur(13px);
}

#roProsumBloom { filter: blur(6px); pointer-events: none; }
/* Pale, not more amber. The county tint already runs to almost opaque orange
   at the top of the scale, so a disc of the same colour over it changes
   nothing you can see -- it just looks like the tint went soft at the edges.
   A warm near-white reads as light coming off the county instead of as more
   paint on it. */
.prosum-bloom { fill: rgba(255, 234, 176, .3); }

/* transparent, not none: an SVG shape filled with `none` is hit-tested on its
   stroke only, so an uncoloured county could be hovered on its border line and
   nowhere else. At night, when every county is at zero and none of them is
   tinted, that turned the whole layer into a label that blinked on and off as
   the pointer crossed each outline. */
.geo-county { fill: transparent; stroke: rgba(125, 165, 215, .22); stroke-width: var(--sw-county, 0.7); }

/* The transmission network. 400 kV is the backbone and reads warm against
   the blue landmass; 220 kV sits behind it, cooler and thinner. The blue
   needs to be well above the landmass tone or it simply disappears. */
.grid-400 { fill: none; stroke: #e0a24a; stroke-width: var(--sw-400, 1); opacity: .65; stroke-linecap: round; }
.grid-220 { fill: none; stroke: #7fc4e8; stroke-width: var(--sw-220, 0.8); opacity: .5; stroke-linecap: round; }

.geo-label {
  fill: #43597e;
  font-size: var(--fs-label, 26px);
  font-weight: 700;
  letter-spacing: .1em;
  text-anchor: middle;
  dominant-baseline: middle;
}

/* The day-ahead price, under each country's initials. Dimmer and much smaller
   than the flow captions on purpose: this view is about what is crossing the
   border, and the price is the reason rather than the subject. */
.geo-price {
  fill: #7d9ac6;
  font-size: var(--fs-price, 13px);
  font-weight: 600;
  text-anchor: middle;
  dominant-baseline: middle;
  paint-order: stroke fill;
  stroke: rgba(7, 16, 29, .8);
  stroke-width: var(--sw-halo, 3px);
  stroke-linejoin: round;
}
/* Romania's own price, set at Bucharest and written like a city label. The
   halo does what a filled plate did, without a box: paint-order puts the stroke
   behind the glyphs, so the number lifts off the counties without a frame
   around it. */
.ro-price-dot {
  fill: #b9cdeb;
  stroke: rgba(9, 20, 36, .85);
  stroke-width: var(--sw-ro, 1.4);
  /* r as a CSS property so it holds a constant on-screen size like the type;
     the attribute stays as the fallback. */
  r: var(--r-city, 3.4px);
}
.ro-price-value {
  fill: #c3d5f0;
  font-size: var(--fs-price, 13px);
  font-weight: 600;
  letter-spacing: .01em;
  dominant-baseline: middle;
  paint-order: stroke fill;
  stroke: rgba(7, 16, 29, .85);
  stroke-width: var(--sw-halo, 3px);
  stroke-linejoin: round;
}

/* County figures for the prosumer layer. Dark ink with a light halo, because
   they sit on the amber fill rather than on the map's own background. */
.county-value {
  fill: #2a1c06;
  font-size: var(--fs-price, 13px);
  font-weight: 700;
  text-anchor: middle;
  dominant-baseline: middle;
  pointer-events: none;
  paint-order: stroke fill;
  stroke: rgba(255, 231, 176, .7);
  stroke-width: var(--sw-halo, 3px);
  stroke-linejoin: round;
}
/* The hovered one carries a name as well, so it is set on the dark plate the
   rest of the map uses rather than trying to sit on the fill. */
.county-value--one {
  fill: #ffe6b0;
  stroke: rgba(7, 16, 29, .9);
}

/* The Danube reading, set like the capital's price: a dot and two lines beside
   it, lifted by a halo rather than a box. */
.danube-dot { fill: #7fc4e8; stroke: rgba(7, 16, 29, .9); stroke-width: 1.2; }
.danube-place {
  fill: #7fc4e8;
  font-size: calc(var(--fs-price, 13px) * .82);
  font-weight: 700;
  text-anchor: start;
  dominant-baseline: middle;
  pointer-events: none;
  paint-order: stroke fill;
  stroke: rgba(7, 16, 29, .85);
  stroke-width: var(--sw-halo, 3px);
  stroke-linejoin: round;
}

.danube-value, .danube-note {
  text-anchor: end;
  paint-order: stroke fill;
  stroke: rgba(7, 16, 29, .85);
  stroke-width: var(--sw-halo, 3px);
  stroke-linejoin: round;
  dominant-baseline: middle;
  pointer-events: none;
}
.danube-value { fill: #7fc4e8; font-size: var(--fs-price, 13px); font-weight: 700; }
.danube-note  { fill: #5f7ba6; font-size: calc(var(--fs-price, 13px) * .82); font-weight: 600; }

/* Cernavoda, in the generation mix's own yellow for nuclear: this is a power
   station, not another river. Both lines run right, into the sea -- see
   drawNuclear() for why. */
.nuc-dot { fill: #f5d547; stroke: rgba(7, 16, 29, .9); stroke-width: 1.2; }
.nuc-place, .nuc-value {
  text-anchor: start;
  dominant-baseline: middle;
  pointer-events: none;
  paint-order: stroke fill;
  stroke: rgba(7, 16, 29, .85);
  stroke-width: var(--sw-halo, 3px);
  stroke-linejoin: round;
}
.nuc-place { fill: #f5d547; font-size: calc(var(--fs-price, 13px) * .82); font-weight: 700; }
.nuc-value { fill: #f5d547; font-size: var(--fs-price, 13px); font-weight: 700; }

/* Invisible, and the only part of a marker a pointer can reach: the text above
   disables pointer events so it cannot swallow a hover meant for the county
   under it. */
.marker-hit { fill: transparent; pointer-events: all; cursor: pointer; }

/* ---------- the cards that open off the map ---------- */

.dnb-card {
  position: absolute;
  z-index: 20;
  width: min(322px, calc(100vw - 12px));
  padding: 9px 12px 8px;
  background: rgba(9, 18, 32, .96);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  box-shadow: 0 16px 38px rgba(2, 6, 14, .62);
  backdrop-filter: blur(3px);
}
.dnb-card[hidden] { display: none; }

.dnb-close {
  position: absolute;
  top: 3px;
  right: 5px;
  border: 0;
  background: none;
  color: var(--ink-faint);
  font: inherit;
  font-size: 19px;
  line-height: 1;
  padding: 3px 6px;
  cursor: pointer;
}
.dnb-close:hover { color: var(--ink); }

.dnb-title {
  display: block;
  color: var(--ink);
  font-size: 13px;
  font-weight: 600;
  padding-right: 18px;
}

/* One line, and the only figures on the card: the day, what it measured, and
   what that is against the normal. */
.dnb-read {
  display: flex;
  align-items: baseline;
  flex-wrap: wrap;
  gap: 5px;
  margin-top: 2px;
  font-size: 12.5px;
  color: var(--ink-dim);
  min-height: 18px;
}
.dnb-read em { font-style: normal; color: var(--ink-faint); }
.dnb-read b { color: #7fc4e8; font-size: 15px; font-weight: 700; }
.dnb-read i { font-style: normal; color: var(--ink-faint); font-size: 11.5px; }
.dnb-read span { color: #93b8dc; }

.dnb-plot { position: relative; height: 150px; margin: 6px 0 2px; cursor: crosshair; }
.dnb-svg { display: block; width: 100%; height: 100%; overflow: visible; }
.dnb-empty {
  margin: 0;
  padding-top: 46px;
  text-align: center;
  color: var(--ink-faint);
  font-size: 12px;
}

.dnb-grid { stroke: var(--line-soft); stroke-width: 1; }
.dnb-axis { fill: var(--ink-faint); font-size: 9.5px; }
.dnb-axis--y { text-anchor: end; }
.dnb-axis--x { text-anchor: middle; }
.dnb-line {
  fill: none;
  stroke: #7fc4e8;
  stroke-width: 1.8;
  stroke-linejoin: round;
  stroke-linecap: round;
}
.dnb-line--glow { stroke: rgba(127, 196, 232, .22); stroke-width: 5.5; }
/* Dashed, and not the river's colour: it is a thirty-year average, not
   something anyone measured this month. */
.dnb-normal {
  fill: none;
  stroke: rgba(163, 195, 229, .7);
  stroke-width: 1.3;
  stroke-dasharray: 5 4;
}
.dnb-forecast { fill: none; stroke: #7fc4e8; stroke-width: 1.5; stroke-dasharray: 2 3; }
.dnb-forecast-dot { fill: rgba(9, 18, 32, .95); stroke: #7fc4e8; stroke-width: 1.5; }
.dnb-cross { stroke: rgba(160, 190, 230, .5); stroke-width: 1; }
.dnb-dot { fill: #7fc4e8; stroke: #0b1626; stroke-width: 1.4; }

.dnb-ranges { display: flex; gap: 4px; margin-top: 2px; }
.dnb-ranges button {
  border: 1px solid var(--line);
  background: none;
  color: var(--ink-faint);
  font: inherit;
  font-size: 11.5px;
  padding: 2px 9px;
  border-radius: 6px;
  cursor: pointer;
}
.dnb-ranges button:hover { color: var(--ink-dim); }
.dnb-ranges button.is-active { background: var(--panel-2); color: var(--ink); }

.dnb-legend {
  display: flex;
  flex-wrap: wrap;
  gap: 4px 12px;
  margin-top: 7px;
  font-size: 11px;
  color: var(--ink-faint);
}
.dnb-legend span { display: flex; align-items: center; gap: 6px; }
.dnb-key { width: 16px; height: 0; flex: none; border-top: 2px solid; }
.dnb-key--masurat { color: #7fc4e8; }
.dnb-key--normal { color: rgba(163, 195, 229, .7); border-top-style: dashed; }
.dnb-key--prognoza { color: #7fc4e8; border-top-style: dotted; }
.nuc-key--productie { color: #7fc4e8; }

.dnb-foot { margin-top: 5px; font-size: 10.5px; color: var(--ink-faint); }

.flow-line  { stroke-width: var(--sw-flow, 2.4); fill: none; stroke-linecap: round; }
/* The whole arrow as one shape. A thin dark edge keeps it legible where it
   crosses the county shading, which is bright amber at midday. */
.flow-body  { stroke: rgba(7, 16, 29, .55); stroke-width: .8; stroke-linejoin: round; }
.flow-node  { fill: #0b1626; stroke-width: var(--sw-node, 2); }

.flow--import .flow-line, .flow--import .flow-node { stroke: var(--import); }
.flow--import .flow-body { fill: var(--import); }
.flow--export .flow-line, .flow--export .flow-node { stroke: var(--export); }
.flow--export .flow-body { fill: var(--export); }
.flow--idle   .flow-line, .flow--idle .flow-node   { stroke: var(--idle); }
.flow--idle   .flow-body { fill: var(--idle); }

/* Dashes running down the shaft into the head. The pattern and the pace are
   set per arrow in JS, from the megawatts -- this only says what it looks
   like. Pale rather than coloured: the body underneath already carries the
   direction colour, and a second tone inside it muddies both.

   Animation, not transition. The reduced-motion block at the bottom of this
   file switches transitions off wholesale and does not touch keyframes, so it
   names these explicitly. */
@keyframes flow-march { to { stroke-dashoffset: 0; } }
.flow-dash {
  fill: none;
  stroke: rgba(236, 244, 255, .62);
  stroke-width: calc(var(--sw-flow, 2.4) * .55);
  stroke-linecap: butt;
  animation: flow-march linear infinite;
}

.flow-value { font-size: var(--fs-value, 20px); font-weight: 700; }
.flow--import .flow-value { fill: var(--import); }
.flow--export .flow-value { fill: var(--export); }
.flow--idle   .flow-value { fill: var(--idle); }
.flow-unit  { fill: var(--ink-faint); font-size: var(--fs-unit, 12px); font-weight: 600; }

.legend {
  position: absolute;
  right: 14px;
  top: 14px;
  display: flex;
  flex-direction: column;
  gap: 7px;
  padding: 11px 15px;
  background: rgba(9, 18, 32, .82);
  border: 1px solid var(--line);
  border-radius: 8px;
  font-size: 13.5px;
  color: var(--ink-dim);
  backdrop-filter: blur(3px);
}
.legend[hidden] { display: none; }
.legend > span { display: flex; align-items: center; gap: 8px; }
/* The rule above beats the browser's own [hidden] { display: none }, so a row
   that hides itself stays on screen -- which is how the day/night row sat in
   the legend while its line was nowhere on the map. Same trap the separator
   fell into. Anything that can hide itself in here needs this. */
.legend > span[hidden] { display: none; }
.legend-arrow { width: 26px; height: 10px; flex: none; }
.legend-arrow path { stroke-width: 1.8; fill: currentColor; stroke: currentColor; }
.legend-arrow--export { color: var(--export); }
.legend-arrow--import { color: var(--import); }

/* A control inside the legend rather than beside it: it turns on a layer whose
   key the legend is already carrying, and a separate strip of chrome for one
   switch is more furniture than the map can spare. */
.legend-toggle {
  display: flex;
  align-items: center;
  gap: 8px;
  border: 1px solid transparent;
  background: none;
  padding: 2px 6px;
  margin: 0 -6px;
  border-radius: 6px;
  color: var(--ink-faint);
  font: inherit;
  font-size: inherit;
  cursor: pointer;
  text-align: left;
}
.legend-toggle[hidden] { display: none; }
.legend-toggle:hover { color: var(--ink-dim); }
.legend-toggle.is-on { color: var(--ink); border-color: rgba(242, 168, 58, .6); }
.legend-swatch {
  width: 12px; height: 12px; flex: none; border-radius: 3px;
  border: 1px dashed rgba(242, 168, 58, .75);
  background: rgba(242, 168, 58, .2);
}
/* Lit, the swatch takes the same amber the counties are painted in and the
   figure beside it stops being grey: this is the one control on the map that
   turns a whole layer on, and dimmed to the colour of a caption it read as a
   note rather than a switch. */
.legend-toggle.is-on .legend-swatch {
  background: #f2a83a;
  border-color: #ffd27a;
  border-style: solid;
}
.legend-toggle em { font-style: normal; color: var(--ink-faint); font-size: 11.5px; }
.legend-toggle.is-on em { color: #ffc75c; font-weight: 700; }

.legend-sep { height: 1px; background: var(--line); margin: 2px 0; }

/* ---------- map: two views ---------- */

/* The frame reads as a control rather than as a caption: darker than the map
   under it, a lighter edge than the panels around it, and a shadow so it sits
   *on* the drawing instead of in it. */
.map-views {
  position: absolute;
  left: 14px;
  top: 14px;
  z-index: 2;
  display: flex;
  padding: 4px;
  gap: 4px;
  background: rgba(7, 14, 26, .9);
  border: 1px solid #2c4a75;
  border-radius: 9px;
  box-shadow: 0 3px 12px rgba(0, 0, 0, .5);
  backdrop-filter: blur(3px);
}
/* Each half names its side with a flag banded across its label, so the pair
   reads as a choice from across the panel instead of as grey-on-grey
   furniture. A band rather than a fill: the map already carries a colour
   scale, and two full flags next to it made three of them.

   Weight is 600 on both, not only on the active one -- app.js measures this
   control as an obstacle when it places the map labels, and a width that
   changes on click moves labels that have nothing to do with the click. */
.map-view {
  position: relative;
  overflow: hidden;
  /* No edge of its own. The outer frame already draws one line around the pair,
     and a second line 4px inside it put three concentric outlines around each
     word. Kept at 1px transparent rather than dropped: app.js measures this
     control when it places the map labels, and a border that appears on click
     would move labels that have nothing to do with the click.

     Neither half gets an edge the other lacks. Giving one to the selected half
     alone made the other look like a label that happened to sit nearby, which
     is the whole reason nobody clicked it. */
  border: 1px solid transparent;
  /* Dark enough that the strip left over above and below the band reads as the
     key itself rather than as haze laid over the flag. The band is 20px on a
     32px key and its wave clips away more, so a good third of the face shows
     through; at the old #24406c that third was a pale blue mist sitting on the
     colours. */
  background: linear-gradient(180deg, #0f1d33 0%, #0b1526 100%);
  color: var(--ink-dim);
  font: inherit;
  font-size: 13px;
  font-weight: 600;
  padding: 6px 12px;
  border-radius: 6px;
  cursor: pointer;
  transition: background .15s ease, border-color .15s ease, color .15s ease;
}
.map-view::before {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  top: 50%;
  height: 20px;
  transform: translateY(-50%);
  background-size: 100% 100%;
  background-repeat: no-repeat;
  /* With the edges gone this gap does the whole job of saying which half is
     chosen, so it has to be wide enough to read across the panel. Not lower
     than this: the resting half still has to look like a flag rather than like
     a key that has been switched off. */
  opacity: .55;
  transition: opacity .15s ease;
}
/* The band runs behind the word, which needs a layer of its own: an absolutely
   positioned pseudo-element paints over ordinary inline text, so without this
   the flag would cover the label instead of passing behind it.

   A one-pixel outline rather than a soft glow. White on the yellow third needs
   something dark against it, but a blurred halo spreads that dark over the
   flag: at this size the two words each sat in their own smudge and the band
   read as fogged rather than as a flag. The outline buys the same contrast
   inside one pixel of the glyph. */
.map-view > span {
  position: relative;
  z-index: 1;
  text-shadow:
    0 1px 0 rgba(0, 0, 0, .9), 0 -1px 0 rgba(0, 0, 0, .9),
    1px 0 0 rgba(0, 0, 0, .9), -1px 0 0 rgba(0, 0, 0, .9),
    0 1px 3px rgba(0, 0, 0, .55);
}
/* Blue-yellow-red, hoist order. */
.map-view[data-view="ro"]::before {
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 120 40' preserveAspectRatio='none'%3E%3Cdefs%3E%3CclipPath id='w'%3E%3Cpath d='M0 7 C 20 1, 40 13, 60 7 S 100 1, 120 7 L 120 33 C 100 39, 80 27, 60 33 S 20 39, 0 33 Z'/%3E%3C/clipPath%3E%3ClinearGradient id='f' x1='0' x2='1'%3E%3Cstop offset='0' stop-color='%23000' stop-opacity='.16'/%3E%3Cstop offset='.18' stop-color='%23fff' stop-opacity='.14'/%3E%3Cstop offset='.38' stop-color='%23000' stop-opacity='.13'/%3E%3Cstop offset='.58' stop-color='%23fff' stop-opacity='.10'/%3E%3Cstop offset='.78' stop-color='%23000' stop-opacity='.13'/%3E%3Cstop offset='1' stop-color='%23fff' stop-opacity='.10'/%3E%3C/linearGradient%3E%3C/defs%3E%3Cg clip-path='url%28%23w%29'%3E%3Crect width='40' height='40' fill='%23002b7f'/%3E%3Crect x='40' width='40' height='40' fill='%23fcd116'/%3E%3Crect x='80' width='40' height='40' fill='%23ce1126'/%3E%3Crect width='120' height='40' fill='url%28%23f%29'/%3E%3C/g%3E%3C/svg%3E");
}
/* The ring of stars cannot survive three pixels, so it lies down into a row of
   them, centred on the blue the way the ring is centred on the flag. It rides
   in as a background image rather than an element of its own, so the whole
   band stays one pseudo-element and the markup stays plain text. */
.map-view[data-view="eu"]::before {
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 120 40' preserveAspectRatio='none'%3E%3Cdefs%3E%3CclipPath id='w'%3E%3Cpath d='M0 7 C 20 1, 40 13, 60 7 S 100 1, 120 7 L 120 33 C 100 39, 80 27, 60 33 S 20 39, 0 33 Z'/%3E%3C/clipPath%3E%3ClinearGradient id='f' x1='0' x2='1'%3E%3Cstop offset='0' stop-color='%23000' stop-opacity='.16'/%3E%3Cstop offset='.18' stop-color='%23fff' stop-opacity='.14'/%3E%3Cstop offset='.38' stop-color='%23000' stop-opacity='.13'/%3E%3Cstop offset='.58' stop-color='%23fff' stop-opacity='.10'/%3E%3Cstop offset='.78' stop-color='%23000' stop-opacity='.13'/%3E%3Cstop offset='1' stop-color='%23fff' stop-opacity='.10'/%3E%3C/linearGradient%3E%3Cpath id='s' d='M0-1 .225-.309 .951-.309 .363.118 .588.809 0 .382 -.588.809 -.363.118 -.951-.309 -.225-.309Z'/%3E%3C/defs%3E%3Cg clip-path='url%28%23w%29'%3E%3Crect width='120' height='40' fill='%23003399'/%3E%3Cg fill='%23ffcc00'%3E%3Cuse href='%23s' transform='translate%2860.00 7.00%29 scale%284%29'/%3E%3Cuse href='%23s' transform='translate%2866.50 8.74%29 scale%284%29'/%3E%3Cuse href='%23s' transform='translate%2871.26 13.50%29 scale%284%29'/%3E%3Cuse href='%23s' transform='translate%2873.00 20.00%29 scale%284%29'/%3E%3Cuse href='%23s' transform='translate%2871.26 26.50%29 scale%284%29'/%3E%3Cuse href='%23s' transform='translate%2866.50 31.26%29 scale%284%29'/%3E%3Cuse href='%23s' transform='translate%2860.00 33.00%29 scale%284%29'/%3E%3Cuse href='%23s' transform='translate%2853.50 31.26%29 scale%284%29'/%3E%3Cuse href='%23s' transform='translate%2848.74 26.50%29 scale%284%29'/%3E%3Cuse href='%23s' transform='translate%2847.00 20.00%29 scale%284%29'/%3E%3Cuse href='%23s' transform='translate%2848.74 13.50%29 scale%284%29'/%3E%3Cuse href='%23s' transform='translate%2853.50 8.74%29 scale%284%29'/%3E%3C/g%3E%3Crect width='120' height='40' fill='url%28%23f%29'/%3E%3C/g%3E%3C/svg%3E");
}
/* The eclipse key has no country to fly, so it flies the thing itself: a night
   sky with the Moon in front of the Sun and the corona around it. Two layers
   rather than one, because the flags are stretched to the width of their key --
   fine for three colour blocks, ruinous for a circle, which came out an egg.
   The sky stretches; the glyph keeps its aspect and sits in the middle of it. */
.map-view[data-view="eclipse"]::before {
  background-image: url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 40 40'><defs><radialGradient id='c' cx='.5' cy='.5' r='.5'><stop offset='.56' stop-color='%23fff3d4' stop-opacity='0'/><stop offset='.65' stop-color='%23fff3d4' stop-opacity='1'/><stop offset='.74' stop-color='%23ffc76f' stop-opacity='.6'/><stop offset='1' stop-color='%23ff9c3c' stop-opacity='0'/></radialGradient></defs><circle cx='20' cy='20' r='19.5' fill='url%28%23c%29'/><circle cx='20' cy='20' r='11' fill='%2303050b'/><circle cx='20' cy='20' r='11.5' fill='none' stroke='%23fff0c8' stroke-width='1.5'/></svg>"),
                    url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 120 40' preserveAspectRatio='none'><defs><clipPath id='w'><path d='M0 7 C 20 1, 40 13, 60 7 S 100 1, 120 7 L 120 33 C 100 39, 80 27, 60 33 S 20 39, 0 33 Z'/></clipPath><linearGradient id='s' x1='0' y1='0' x2='0' y2='1'><stop offset='0' stop-color='%232a4a91'/><stop offset='.5' stop-color='%2316296b'/><stop offset='1' stop-color='%230a1030'/></linearGradient></defs><g clip-path='url%28%23w%29'><rect width='120' height='40' fill='url%28%23s%29'/><g fill='%23eef3ff'><circle cx='13' cy='13' r='1.1' opacity='.9'/><circle cx='27' cy='27' r='.9' opacity='.7'/><circle cx='97' cy='12' r='1' opacity='.85'/><circle cx='108' cy='27' r='.9' opacity='.65'/><circle cx='86' cy='30' r='.8' opacity='.6'/></g></g></svg>");
  background-size: auto 100%, 100% 100%;
  background-position: center, center;
}
/* Full words where there is room for them, two letters where there is not.
   This control floats over the drawing, and at the width of "Romania | Europa"
   it covered Ukraine's initials and half its price on a phone. */
.view-short { display: none; }
.map-view:hover {
  color: var(--ink);
  background: linear-gradient(180deg, #16294a 0%, #0f1c30 100%);
}
.map-view:hover::before { opacity: .75; }
.map-view:focus-visible { outline: 2px solid #ffcc00; outline-offset: 2px; }
/* Chosen: its flag at full strength and its label at full white, against a
   resting half that keeps both at part strength. The state is carried by the
   flag and the word alone. Every other way of saying it -- a lighter fill, a
   bright outline, a white hairline along the top -- put a pale layer over the
   colours, and a pale layer over a flag is what reads as fog. */
.map-view.is-on {
  color: var(--ink);
  background: linear-gradient(180deg, #14243f 0%, #0d1829 100%);
}
.map-view.is-on::before { opacity: 1; }

/* The European frame is nearly square where the Romanian one is landscape, so
   letting it letterbox inside the same box wastes a third of the panel. */
.panel--map.is-eu .map { min-height: 420px; }

/* Countries outside the day-ahead coupling -- Britain, Belarus, Russia, Turkey,
   Bosnia. Their own tone rather than --land, which is what the Romanian map
   paints its neighbours: at 1:1 with the sea underneath they read as water, and
   Europe appeared to have holes in it. Light enough to be unmistakably land,
   flat enough that the eye never mistakes them for a price. */
.eu-land {
  fill: #29405f;
  stroke: #101d30;
  stroke-width: 0.8;
  stroke-linejoin: round;
  /* Day-ahead prices land once a day, so this fires on the first paint after
     midnight and when the view is switched -- rarely, and worth it there:
     thirty countries changing tone at once is the one moment the map has a
     before and an after. */
  transition: fill .6s ease;
}
/* Priced but unpainted -- the fetch missed it, or its currency was refused.
   A step above the countries that are not in the coupling at all, and still
   far duller than any point on the scale so it never reads as cheap. */
/* One halo for the whole continent. The countries tile, so the group's
   silhouette is the coastline and the shadow lands there and nowhere else --
   which is the only edge on this map that wants lifting off the sea. */
#euLand { filter: drop-shadow(0 0 7px rgba(88, 142, 208, .34)); }

/* The day/night boundary at the hour the prices are for. Blurred, because
   dusk is not a line: a hard edge across the continent reads as a clip path
   or a rendering fault.

   The line and nothing else. A filled night side came first and was dropped.
   Over the sea and over the countries that carry no price, dark on dark read
   as haze rather than as nightfall -- and the sea is the largest surface in
   the frame. It also cost every price some contrast to say something the hour
   printed above it already said. With the wash gone the line can afford to
   carry more, so it does. */
#euNightside { pointer-events: none; }
.eu-dusk { fill: none; stroke: rgba(255, 178, 98, .55); stroke-width: 7; filter: blur(4px); }

/* Night, as a shadow over the fill rather than a colour of its own: the price
   colour underneath is the reading, and it has to survive being darkened. */
.eu-nightfill { fill: rgba(2, 4, 10, .48); stroke: none; }

/* Daylight spilling off the boundary, on the lit side only.
   Adrian asked whether the day side should be brighter rather than the night
   side darker. Over the whole half it is the wash we already removed, in
   mirror: a lit Poland reads as a dearer Poland, and the fill is the reading
   on this map. Hugging the line it says the same thing and touches nothing
   more than a country's own edge. The path is the boundary stepped onto the
   lit side, so the fall-off follows the curve rather than a straight
   gradient that would drift off it where it bends. */
.eu-daylight {
  fill: none;
  stroke: rgba(255, 206, 140, .17);
  stroke-width: 30;
  filter: blur(13px);
}

.eu-land--priced { fill: #35507a; }
.eu-land.is-priced { stroke: rgba(8, 16, 28, .55); }
.eu-land--priced:hover { stroke: var(--ink); stroke-width: 1.6; }

.eu-land.is-picked { stroke: #ffe6a8; stroke-width: 1.8; }

/* Flow arrows.
   Warm and light so they carry across the cold end of the price scale, with a
   dark edge so they still read over the yellows and oranges at the other end --
   a gold arrow on a 90 EUR country is otherwise invisible. Neutral on purpose:
   the fill already carries a colour scale, and a second one competing with it
   would make the map harder to read, not richer. */
.eu-flow { pointer-events: none; }
/* One filter on the group rather than one per arrow: eighty filtered elements
   is a measurable cost on a phone, and the shadow only has to lift the layer
   off the fill, not each arrow off its neighbour. */
#euFlows { filter: drop-shadow(0 1px 1.5px rgba(0, 0, 0, .5)); }
.eu-arrow {
  fill: #ffd267;
  stroke: rgba(6, 13, 24, .7);
  stroke-width: 1.1;
  stroke-linejoin: round;
}
/* The trail feeding each arrow's tail. Gold like the arrow rather than pale
   like the Romanian one: here the arrow is a small solid shape on a coloured
   country, and a white trail behind it reads as a separate object. */
.eu-dash {
  fill: none;
  stroke: #ffd267;
  stroke-width: 2.2;
  stroke-linecap: round;
  opacity: .7;
  animation: flow-march linear infinite;
}

.eu-flow-value {
  fill: #ffe6b0;
  font-weight: 700;
  text-anchor: middle;
  dominant-baseline: central;
}

.eu-cur { font-size: .66em; font-weight: 600; opacity: .8; }

.eu-value {
  font-weight: 700;
  text-anchor: middle;
  dominant-baseline: central;
  pointer-events: none;
}
.eu-leader { stroke: rgba(190, 212, 245, .42); stroke-width: 1; }
/* Quieter than an inline number in every respect -- smaller, dimmer ink, a
   softer plate. A country that needs a leader is a footnote, not a headline. */
.eu-plate  { fill: rgba(11, 21, 36, .82); stroke: rgba(150, 180, 220, .3); stroke-width: 1; }
.eu-value--aside { font-weight: 600; }

.legend--eu { width: 216px; }
.eu-scale-head { color: var(--ink); font-size: 12.5px; }
.legend .eu-scale { position: relative; display: block; }
.eu-bar { display: block; height: 9px; border-radius: 3px; }
.eu-ticks { position: relative; display: block; height: 14px; }
.eu-ticks em {
  position: absolute;
  transform: translateX(-50%);
  font-style: normal;
  font-size: 11px;
  color: var(--ink-faint);
}
.eu-note { color: var(--ink-faint); font-size: 11.5px; line-height: 1.35; }

.legend .eu-pick {
  display: flex;
  flex-direction: column;
  /* .legend > span centres its children; in a column that centres them
     horizontally, and the readout was the only thing on the page not aligned
     with everything else. */
  align-items: flex-start;
  gap: 1px;
  padding-top: 8px;
  border-top: 1px solid var(--line);
}
.eu-pick[hidden] { display: none; }
.eu-pick b { color: var(--ink); font-weight: 600; }
/* Two classes deep, because .eu-pick span already sets both and would win. */
.eu-pick .eu-pick-note { color: var(--ink-faint); font-size: 11.5px; }
.eu-pick .eu-pick-net { color: #e3c07a; }
.eu-pick span { color: var(--ink-dim); font-size: 12.5px; }
.legend-wire { width: 26px; height: 2px; flex: none; border-radius: 1px; }
.legend-wire--400 { background: #e0a24a; }
.legend-wire--220 { background: #7fc4e8; }
/* Soft-edged, like the line it stands for. A crisp 2px bar next to two other
   crisp 2px bars would say this is a third kind of wire. */
.legend-wire--dusk {
  height: 4px;
  background: linear-gradient(rgba(255, 178, 98, 0), rgba(255, 178, 98, .85), rgba(255, 178, 98, 0));
}

/* ---------- sources list ---------- */

.sources { list-style: none; margin: 0; padding: 5px 0; }

.sources li {
  display: grid;
  grid-template-columns: 12px 1fr auto auto;
  align-items: center;
  gap: 11px;
  padding: 5px 16px;
}

/* How much of the fuel's installed capacity is running. The track is always
   drawn, even where there is nothing to fill it with: an absent track would
   pull that row's megawatts out of line with every row above it, and this
   column has three empty cells on a normal day. */
/* Names the bars and nothing else, in the column they live in. A note in the
   panel head fought the title for a row that already carries a total: at 1366
   the title folded in two, and once it was stopped from folding the note was
   squeezed to a five-pixel sliver -- absent on the width most people have. */
.sources li.src-head { padding-top: 2px; padding-bottom: 1px; }
/* Dim rather than faint. It is the only thing on the panel that says what the
   column under it measures, and at the faint step it was quiet enough to scan
   past -- which is how the bar gets read as megawatts. */
.src-cap-head {
  font-size: 9.5px;
  font-weight: 600;
  letter-spacing: .04em;
  color: var(--ink-dim);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* The track has to be as legible as the fill, because the fill means nothing
   without it: this bar is a share of each fuel's own capacity, not a length
   proportional to megawatts. At .13 the empty part was barely there, a 47% bar
   read as "a bar this long", and biomass at 56 MW looked like coal at 797 --
   which is exactly what a reader wrote in to say. Both are running at about
   half of what they have installed, and with the box visible that is what the
   two bars say. */
.src-cap {
  height: 4px;
  border-radius: 3px;
  background: rgba(125, 165, 215, .13);
  box-shadow: inset 0 0 0 1px rgba(138, 174, 220, .28);
  overflow: hidden;
  cursor: help;
}
/* The bar is reachable by tab and by tap, so it needs the focus ring the rest
   of the page has. Offset, because the track is four pixels tall and a ring
   drawn on its edge would read as part of the fill. */
.src-cap:focus-visible { outline: 2px solid var(--ink-dim); outline-offset: 3px; }
/* No installed figure published, so no box: an empty gauge is a reading, and
   this row has none to give. */
.src-cap--none { background: none; box-shadow: none; cursor: default; }

/* The unit on a headline figure, once it has something to say. A dotted rule
   is the whole affordance: enough that a reader sees there is more here,
   little enough that four of them across the top row change nothing. */
.unit-tip {
  cursor: help;
  border-bottom: 1px dotted rgba(142, 163, 196, .55);
  padding-bottom: 1px;
}
.unit-tip:focus-visible { outline: 2px solid var(--ink-dim); outline-offset: 2px; }
.src-cap i {
  display: block;
  height: 100%;
  border-radius: 3px;
  /* The figure moves every thirty seconds and the bar is short, so a jump of a
     few pixels reads as a flicker rather than as a change. */
  transition: width .5s ease;
}

.swatch { width: 12px; height: 12px; border-radius: 3px; }
/* Name over bar, not name beside bar. A column of its own cost 72px of the
   row, which is more than the side panel has to spare: at 1366 it clipped
   "Hidrocarburi" to "Hidroca...". Under the name the bar costs four pixels of
   height and no width at all, and it reads as belonging to the fuel above it
   rather than as a fifth column. */
.src-name {
  display: flex;
  flex-direction: column;
  gap: 4px;
  min-width: 0;
  color: var(--ink);
}
.src-name b { font-weight: 400; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.src-val  { white-space: nowrap; }
.src-val b { font-weight: 600; }
.src-val i { font-style: normal; font-size: 11.5px; color: var(--ink-faint); margin-left: 3px; }
.src-pct  { color: var(--ink-dim); width: 54px; text-align: right; white-space: nowrap; }

/* ---------- flow by border ---------- */

.panel-note { color: var(--ink-faint); font-size: 11.5px; white-space: nowrap; }

/* Five overlapping traces in one small box: at 132px the lines spent most of
   their time on top of each other and the shape of any single border was
   guesswork. The extra height is where they separate. */
/* pan-y, not the default: without it the browser claims a horizontal drag for
   page scrolling, fires pointercancel, and the readout never appears on a
   phone. Vertical swipes still scroll, which is what you want on a chart whose
   only meaningful axis is horizontal. */
.brd-chart {
  position: relative;
  height: 186px;
  padding: 8px 12px 0;
  cursor: crosshair;
  touch-action: pan-y;
}
.brd-chart svg { display: block; width: 100%; height: 100%; overflow: visible; }
.brd-line { fill: none; stroke-width: 1.5; stroke-linejoin: round; stroke-linecap: round; }
.brd-zero { stroke: rgba(176, 206, 244, .6); stroke-width: 1; stroke-dasharray: 3 3; }
.brd-axis-label { fill: var(--ink-faint); font-size: 9.5px; }
.brd-cross { stroke: rgba(160, 190, 230, .55); stroke-width: 1; }
.brd-dot { stroke: #0b1626; stroke-width: 1.2; }

/* ---------- exchange table ---------- */

.table-scroll { overflow-y: auto; flex: 1; min-height: 0; }

.xtable { width: 100%; border-collapse: collapse; font-size: 14px; }
.xtable th {
  position: sticky;
  top: 0;
  background: #0e1a2c;
  color: var(--ink-faint);
  font-weight: 500;
  font-size: 12.5px;
  text-align: left;
  padding: 8px 16px;
  border-bottom: 1px solid var(--line-soft);
  z-index: 1;
}
.xtable td { padding: 6px 16px; border-bottom: 1px solid rgba(30, 51, 85, .4); }
.xtable tr:last-child td { border-bottom: 0; }
.xtable .num { text-align: right; white-space: nowrap; }
.xtable .num b { font-weight: 600; }
.xtable .num i { font-style: normal; font-size: 11.5px; color: var(--ink-faint); margin-left: 3px; }

.dir--import { color: var(--import); }
.dir--export { color: var(--export); }
.dir--idle   { color: var(--ink-faint); }

/* The scheduled figure, directly under the realised one. Deliberately quieter
   than the heading total: it is the reference the big number is read against,
   not a second headline. */
/* The two summary rows under the border chart. Same geometry as .panel-head --
   caption left, figure right -- so the realised and the scheduled number sit
   in one column and can be compared by eye. That comparison is why they are
   adjacent at all. */
.panel-sub {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 12px;
  margin: 0;
  padding: 4px 16px 9px;
  font-size: 12.5px;
  color: var(--ink-faint);
}
.panel-sub .sub-label { min-width: 0; }
.panel-sub em { font-style: normal; font-weight: 600; }

/* The rule separates the pair from the chart legend, not the two rows from
   each other -- they are one block and read as one. */
.panel-sub--now {
  border-top: 1px solid var(--line-soft);
  padding-top: 9px;
  padding-bottom: 2px;
}

.sub-total { white-space: nowrap; }
.sub-total b { font-size: 15px; font-weight: 700; color: var(--ink-dim); }
.sub-total i { font-style: normal; font-size: 12px; color: var(--ink-faint); margin-left: 2px; }

/* What is happening now outranks what was planned; the scheduled row stays
   the dimmer of the two, caption included. */
.panel-sub--now { font-size: 14px; color: var(--ink-dim); }
.panel-sub--now .sub-total b { font-size: 18px; color: var(--ink); }

/* Folded-away interconnections. */
.xtable-more td { padding: 4px 16px; border-bottom: 0; }
.xtable-more button {
  background: none;
  border: 0;
  padding: 2px 0;
  font: inherit;
  font-size: 11.5px;
  color: var(--ink-faint);
  cursor: pointer;
}
.xtable-more button:hover { color: var(--ink); }
.xtable tr.is-idle td { color: var(--ink-faint); }

/* ---------- chart ---------- */

.panel--chart, .panel--mix {
  display: flex;
  flex-direction: column;
  min-width: 0;
  min-height: 0;
  /* On a short window the plot hits its own minimum and would otherwise spill
     over the legend below it. */
  overflow: hidden;
}

.chart-head { flex-wrap: wrap; align-items: center; row-gap: 7px; }
.chart-head h2 { margin-right: auto; }

.chart-series { display: flex; gap: 5px; flex-wrap: wrap; flex-basis: 100%; }

.ch-toggle {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  padding: 2px 9px;
  border: 1px solid var(--line);
  border-radius: 999px;
  background: transparent;
  color: var(--ink-faint);
  font: inherit;
  font-size: 12.5px;
  cursor: pointer;
  transition: color .12s, border-color .12s;
}
.ch-toggle i {
  width: 9px; height: 9px; border-radius: 50%;
  background: var(--c);
  opacity: .3;
}
.ch-toggle.is-on { color: var(--ink); border-color: var(--c); }

/* Split down the middle for a series drawn in two colours, dot and border
   both. After `.ch-toggle.is-on`, not before it: same specificity, and written
   above it the plain rule's solid border-color won and the pill kept one
   colour however the gradient was declared. */
.ch-toggle--split i {
  background: linear-gradient(90deg, var(--c) 0 50%, var(--c2) 50% 100%);
}
.ch-toggle--split.is-on {
  border-color: transparent;
  background:
    linear-gradient(var(--panel), var(--panel)) padding-box,
    linear-gradient(90deg, var(--c) 0 50%, var(--c2) 50% 100%) border-box;
}
.ch-toggle.is-on i { opacity: 1; }
.ch-toggle:hover { color: var(--ink); }
.ch-toggle:focus-visible { outline: 2px solid var(--sold); outline-offset: 2px; }

.chart-ranges { display: flex; gap: 2px; }
.chart-ranges button {
  padding: 2px 11px;
  border: 1px solid var(--line);
  background: transparent;
  color: var(--ink-faint);
  font: inherit;
  font-size: 12.5px;
  cursor: pointer;
}
.chart-ranges button:first-child { border-radius: 6px 0 0 6px; }
.chart-ranges button:last-child { border-radius: 0 6px 6px 0; }
.chart-ranges button + button { border-left: 0; }
.chart-ranges button:hover { color: var(--ink); }
.chart-ranges button.is-active { color: var(--ink); background: var(--panel-2); border-color: #2b4a75; }
.chart-ranges button:focus-visible { outline: 2px solid var(--sold); outline-offset: -2px; }

/* The two views of this panel. Built on the range buttons' own segmented look
   rather than a second control language, but sized like the heading it
   replaces -- these name what the panel is, they do not adjust it. */
.chart-views { display: flex; gap: 2px; margin-right: auto; }
.chart-views button {
  padding: 3px 12px;
  border: 1px solid var(--line);
  background: transparent;
  color: var(--ink-faint);
  font: inherit;
  font-size: 14px;
  font-weight: 600;
  cursor: pointer;
}
.chart-views button:first-child { border-radius: 6px 0 0 6px; }
.chart-views button:last-child { border-radius: 0 6px 6px 0; }
.chart-views button + button { border-left: 0; }
.chart-views button:hover { color: var(--ink); }
.chart-views button.is-active { color: var(--ink); background: var(--panel-2); border-color: #2b4a75; }
.chart-views button:focus-visible { outline: 2px solid var(--sold); outline-offset: -2px; }

.chart-units[hidden] { display: none; }
.chart-ranges[hidden] { display: none; }
.chart-series[hidden] { display: none; }

.chart-wrap { position: relative; flex: 1; min-height: 0; padding: 4px 4px 0; }
.chart-wrap[hidden] { display: none; }

/* ---------- installed capacity by source ---------- */

.cap-wrap { position: relative; padding: 6px 14px 10px; }
.cap-wrap[hidden] { display: none; }
.mix-legend[hidden] { display: none; }
.cap-chart svg { display: block; width: 100%; }
.cap-name { fill: var(--ink); font-size: 12px; }
.cap-val  { fill: var(--ink-dim); font-size: 12px; font-weight: 600; }
.cap-pct  { fill: var(--ink-faint); font-size: 11.5px; }
.cap-note { fill: var(--ink-faint); font-size: 10.5px; }
.cap-bar  { stroke: none; }
.cap-foot {
  margin: 8px 0 0;
  font-size: 11.5px;
  line-height: 1.45;
  color: var(--ink-dim);
}

/* ---------- day-ahead price for today ---------- */

.chart--pzu { cursor: crosshair; }
.pzu-ytick, .pzu-xtick { fill: var(--ink-faint); font-size: 10.5px; }
.pzu-marklab { fill: var(--ink-dim); font-size: 10.5px; }
.pzu-nowlab  { fill: var(--ink-dim); font-size: 10.5px; }
.pzu-zero { stroke: rgba(176, 206, 244, .55); stroke-width: 1; stroke-dasharray: 3 3; }
.pzu-now  { stroke: rgba(160, 190, 230, .45); stroke-width: 1; }
.pzu-line { fill: none; stroke-width: 1.8; stroke-linejoin: round; }
.pzu-area { stroke: none; }
/* The hours already behind us are context; the ones ahead are the reason this
   chart exists, so they carry the weight. */
.pzu-area--past { opacity: .12; }
.pzu-area--next { opacity: .26; }
.pzu-line--past { opacity: .45; }
.pzu-line--next { opacity: 1; }
.pzu-mark { fill: none; stroke: var(--ink-dim); stroke-width: 1.4; }

.pzu-tip {
  position: absolute;
  z-index: 6;
  padding: 5px 9px;
  background: var(--panel-2);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  box-shadow: 0 8px 24px rgba(0, 0, 0, .45);
  font-size: 12px;
  white-space: nowrap;
  pointer-events: none;
  color: var(--ink-dim);
}
.pzu-tip[hidden] { display: none; }
.pzu-tip b { color: var(--ink); font-weight: 600; }
.pzu-tip i { font-style: normal; color: var(--ink-faint); }

.chart {
  width: 100%;
  height: 100%;
  min-height: 90px;
  touch-action: pan-y;
  cursor: crosshair;
}

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

.mix-area { stroke: none; }

/* A hairline that crisps the boundary, not an outline that draws around the
   band. At 2px and full opacity every layer got a bright rim, and the thin
   ones -- biomass, storage -- were nothing BUT rim: a green and a pink stripe
   pasted over the stack, which is what made the whole plot look drawn rather
   than measured. */
.mix-edge { fill: none; stroke-width: 1; opacity: .45; stroke-linejoin: round; }
/* The estimated layer's outline is dashed -- the only mark in the mix that
   says one of these bands is a model and the rest are meters. Declared after
   .mix-edge so its dasharray, width and opacity win. It stays a little
   stronger than the rest, because that distinction has to survive. */
.mix-edge--est { stroke-dasharray: 4 3; stroke-width: 1; opacity: .5; }

/* Direct labels on the three thickest layers, at the right edge. Text wears
   ink tokens, never the series colour -- only the dot next to it does. */
.mix-tag { fill: var(--ink-dim); font-size: 11.5px; }
.mix-tag-val { fill: var(--ink-faint); font-size: 11px; }

.mix-legend {
  display: flex;
  flex-wrap: wrap;
  gap: 1px 9px;
  padding: 4px 11px 7px;
  font-size: 10.5px;
  color: var(--ink-dim);
}
.mix-legend span { display: inline-flex; align-items: center; gap: 5px; white-space: nowrap; }
.mix-legend i { width: 9px; height: 9px; border-radius: 2px; flex: none; }
/* A source sitting at zero is still real information -- it is generating
   nothing right now -- but it should not compete with the ones that are. */
.mix-legend .is-zero { opacity: .4; }

.mix-hover-row { font-size: 11.5px; font-weight: 600; }
.mix-hover-box { fill: rgba(9, 18, 32, .92); stroke: var(--line); stroke-width: 1; }
.chart.is-dragging { cursor: grabbing; }
.chart svg { display: block; width: 100%; height: 100%; }

.ch-grid   { stroke: rgba(46, 74, 116, .35); stroke-width: 1; }
.ch-axis   { stroke: var(--line); stroke-width: 1; }
.ch-cross  { stroke: rgba(160, 190, 230, .5); stroke-width: 1; stroke-dasharray: 3 3; }
.ch-gap    { stroke-dasharray: 4 5; opacity: .28; }
/* The metered figure, under the line that includes the rooftop estimate.
   Dashed and dimmer: it is the reference the solid line is read against, not a
   second reading of its own. */
.ch-measured { stroke-dasharray: 4 4; stroke-width: 1.4; opacity: .75; }
.ch-zero   { stroke: rgba(176, 206, 244, .8); stroke-width: 1.4; stroke-dasharray: 7 5; }
.ch-zero-label { fill: #8ba6c9; font-size: 10.5px; letter-spacing: .3px; }
/* Hangs under the solar line: same indent as the source name, quieter than a
   source of its own, because it is an estimate rather than a reading. */
/* An estimate sitting among measurements. Same grid as the rows above it so
   the figures line up in one column, but hollow swatch and dimmer ink: this
   one is a model, and it should not read as another meter. */
.sources li.src-est { color: var(--ink-dim); }
.src-est .src-val b { font-weight: 600; color: var(--ink-dim); }
.swatch--est {
  background: rgba(242, 168, 58, .22);
  border: 1px dashed rgba(242, 168, 58, .7);
}

/* Under the panel head, above the list: measured generation plus the rooftop
   estimate. Reads as a continuation of the header figure, which is what the
   leading "+" is doing. */
.panel-sub--prosum {
  padding: 6px 16px 2px;
  border-bottom: 1px solid var(--line-soft);
  padding-bottom: 8px;
}
.panel-sub--prosum[hidden] { display: none; }
.src-note em { font-style: normal; opacity: .75; }

.ch-line   { fill: none; stroke-width: 1.8; stroke-linejoin: round; stroke-linecap: round; }
.ch-xlabel, .ch-ylabel { fill: var(--ink-faint); font-size: 11px; }

.chart-empty {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  text-align: center;
  padding: 0 24px;
  color: var(--ink-faint);
  font-size: 13.5px;
  pointer-events: none;
}
.chart-empty[hidden] { display: none; }

.ch-hover-dot { stroke: #0b1626; stroke-width: 1.5; }
.ch-hover-label { font-size: 12px; font-weight: 700; paint-order: stroke; stroke: rgba(7,13,24,.85); stroke-width: 3.5; stroke-linejoin: round; }
.ch-hover-unit { font-size: 9.5px; font-weight: 600; opacity: .75; }
.ch-hover-time { fill: var(--ink-dim); font-size: 11px; paint-order: stroke; stroke: rgba(7,13,24,.9); stroke-width: 3; stroke-linejoin: round; }

.chart-hint {
  margin: 0;
  padding: 2px 4px 0;
  color: var(--ink-faint);
  font-size: 11px;
}

/* ---------- footer ---------- */

.footer {
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  gap: 4px 16px;
  padding: 12px 22px;
  border-top: 1px solid var(--line-soft);
  color: var(--ink-faint);
  font-size: 12.5px;
}

/* Last, and pinned right even when the middle span is empty -- which it is
   until the first payload arrives. */
.foot-contact { white-space: nowrap; }
.foot-contact a { color: inherit; text-decoration: none; }
.foot-contact a:hover { color: var(--ink-dim); text-decoration: underline; }

/* A step lighter than the rest of the footer. It is the one line here that
   changes while you watch, so it earns being read first. */
.foot-viewers {
  margin-left: auto;
  color: var(--ink-dim);
  /* Wraps rather than pushing the page wider. It used to be nowrap, which was
     harmless while it read "184 cu ochii pe retea" and stopped being harmless
     the day it grew "· din care 173 RO · 31 EU": twenty pixels over the edge of
     a phone, and the browser answers that by zooming the whole page out. */
  min-width: 0;
}

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

/* Two columns: the charts drop under the map, which then has the whole width
   of the left column and the figures keep theirs. Held off until the three
   columns genuinely stop fitting -- 1366 is a very common laptop, and putting
   the charts back under everything there brings back both the stretched-out
   line and the scrolling this layout removed. */
@media (max-width: 1279px) {
  .layout { grid-template-columns: minmax(0, 1fr) 380px; grid-template-rows: auto auto clamp(360px, 52vh, 640px) auto; }
  .panel--map { grid-column: 1; grid-row: 3; }
  .side { grid-column: 2; grid-row: 3 / span 2; }
  .charts { grid-column: 1; grid-row: 4; }
  .panel--chart, .panel--mix { flex: none; min-height: 300px; }
}

/* Single column: the grid no longer has a viewport-sized row to hand out,
   so the map needs its own height or it collapses to nothing. */
@media (max-width: 1180px) {
  /* Stacked, the page scrolls as a whole: release the viewport-height
     lock or the columns shrink under their content and hit the footer. */
  html, body { height: auto; }
  .layout { grid-template-columns: minmax(0, 1fr); grid-template-rows: auto auto auto auto auto; min-height: auto; }
  .panel--map { grid-column: 1; grid-row: 3; height: min(64vw, 540px); }
  .charts { grid-column: 1; grid-row: 4; }
  .side { grid-column: 1; grid-row: 5; }
  .panel--flex { flex: none; }
  .table-scroll { overflow: visible; }
}

@media (max-width: 860px) {
  .topbar { grid-template-columns: 1fr auto; row-gap: 8px; padding: 12px 14px; }
  .page-title { grid-column: 1 / -1; grid-row: 2; font-size: 21px; justify-content: center; }
  .brand-text span { display: none; }
  .clock { font-size: 13px; }
  .layout { --pad: 14px; padding: 12px var(--pad) 16px; }
  .kpis { grid-template-columns: repeat(2, 1fr); }
  .kpi:nth-child(3) { border-left: 0; }
  .kpi:nth-child(n+3) { border-top: 1px solid var(--line-soft); }
  /* Two stacked rows instead of two side-by-side slots; the divider mirrors
     the KPI tiles' own border-top between rows, shown only when both slots
     are actually on screen. */
  .band { grid-template-columns: 1fr; gap: 8px; }
  .band-slot--price:not([hidden]) + .band-slot--fact {
    border-top: 1px solid var(--line-soft);
    padding-top: 8px;
  }
  /* Two narrow columns. The value and its unit must stay on one line; only
     the direction word ("import"/"export") drops below, and the tile is
     tightened enough that "MW" is never the thing that wraps. */
  .kpi { padding: 10px 14px; }
  .kpi-value { flex-wrap: wrap; column-gap: 5px; }
  .kpi-value b { font-size: 23px; }
  .kpi-value i { font-size: 14px; }
  .kpi-value em { flex-basis: 100%; margin-top: -1px; }
  .panel--map { height: auto; }
  /* Matching the viewBox aspect exactly means "meet" has nothing to letterbox,
     so the panel is all map instead of a band of dead space above and below. */
  .map { flex: none; height: auto; aspect-ratio: 842 / 620; min-height: 0; }
  .map svg { inset: 4px; width: calc(100% - 8px); height: calc(100% - 8px); }
  .legend {
    position: static;
    flex-direction: row;
    flex-wrap: wrap;
    align-items: center;
    gap: 5px 10px;
    margin: 0 10px 10px;
    padding: 7px 10px;
    font-size: 12px;
    backdrop-filter: none;
  }
  /* Two classes deep: `.legend > span` sets display:flex and outranks a bare
     `.legend-sep`, so the hidden separator stayed a flex item one pixel tall
     and pushed the last pair onto a second row. */
  .map-view {
    font-size: 12px;
    font-weight: 600;
    letter-spacing: .04em;
    padding: 5px 9px;
  }
  .view-long { display: none; }
  .view-short { display: inline; }

  /* Globe under the map, not beside it.
     Side by side, the globe took a quarter of a panel that is only 370px wide
     to begin with, and what was left gave the map a frame 430 projection units
     across -- narrow enough to cut Iceland and the whole Atlantic off the left
     edge, which is where this eclipse comes from. Stacked, the map gets the
     full width back and the frame doubles. */
  .eclipse-stage { flex-direction: column; gap: 6px; }
  .eclipse-globe {
    order: 2;
    flex: 0 0 auto;
    max-width: none;
    width: 100%;
    height: 132px;
    gap: 4px;
  }
  .eclipse-flat { order: 1; flex: 1 1 auto; min-height: 0; }

  .legend > .legend-sep { display: none; }
  /* Small enough that all four pairs fit on one line at 390px. They are
     mnemonics next to their own words, not diagrams to be read on their own. */
  .legend > span { gap: 6px; }
  .legend-arrow { width: 19px; height: 8px; }
  .legend-arrow path { stroke-width: 2.6; }
  .legend-wire { width: 17px; }

  /* The row-and-wrap treatment suits the Romanian legend, which is a list of
     short pairs. The European one is a scale with a caption under it: laid out
     as a row its gradient bar has no intrinsic width and collapses to nothing,
     leaving a stray "200" tick beside the heading. */
  .legend--eu {
    flex-direction: column;
    align-items: stretch;
    width: auto;
  }
  .legend .eu-scale { width: 100%; }

  /* Europe is nearly square; Romania is landscape. Sharing one aspect-ratio
     letterboxes whichever view is not the one it was written for. */
  .panel--map.is-eu .map { aspect-ratio: 1000 / 1030; min-height: 0; }
  /* Taller than the other two, because the globe sits under the map here and
     takes a fixed slice of the height with it. At the shared aspect the map
     was left 126px tall and the frame stretched to 2600 units -- a quarter of
     the planet, with Europe a smudge in the middle. */
  .panel--map.is-eclipse .map { aspect-ratio: 360 / 520; min-height: 0; }
  .banner { margin: 10px 14px -2px; }
  .footer { flex-direction: column; gap: 4px; }
  /* The column turns margin-left:auto into cross-axis alignment, which leaves
     the count hanging alone on the right below two left-aligned lines. */
  .foot-viewers { margin-left: 0; }
  .panel-head { flex-wrap: wrap; }
}

/* Below 640px the old single row could not hold the brand, the switcher, the
   clock and the language pair at once -- the switcher sat on top of the mark
   and "EN" fell off the right edge. Dropping the mark made it fit and left the
   corner looking empty instead of composed.

   So the switcher gets a row of its own and the identity gets its row back:

     row 1   mark + wordmark + subtitle          clock   RO | EN
     row 2   page title
     row 3   Electricitate | Gaze

   `display: contents` on the right-hand cluster is what allows it: its three
   children become grid items in their own right, so two of them can stay on
   the first row while the switcher moves to the third. */
@media (max-width: 640px) {
  .topbar { grid-template-columns: auto 1fr auto; }
  .brand { grid-column: 1; grid-row: 1; }
  .topbar-right { display: contents; }
  .clock { grid-column: 2; grid-row: 1; justify-self: end; }
  .lang { grid-column: 3; grid-row: 1; }
  .page-title { grid-column: 1 / -1; grid-row: 2; }
  .doc-switch { grid-column: 1 / -1; grid-row: 3; justify-self: center; }
  /* Hidden since 860px, where it was competing with the switcher for the same
     strip. On its own row it fits, and it is the line that makes the corner
     read as a header rather than a stray icon. */
  .brand-text span { display: block; }
}

/* Below this the identity row runs out of width, so it gives up the date --
   the seconds are the half that says the page is live -- and the brand set
   shrinks a step. The wordmark stays: it is what the corner is for. */
@media (max-width: 480px) {
  .clock-date { display: none; }
  .brand-mark { height: 27px; }
  .brand { gap: 9px; }
  .brand-text strong { font-size: 14px; }
  .brand-text span { font-size: 11px; }
  .clock { font-size: 12.5px; }
  .page-title { font-size: 19px; }
  .topbar { padding: 10px 12px; }
  .layout { --pad: 12px; padding: 10px var(--pad) 14px; }
  .banner { margin: 8px 12px -2px; }
}

@media (prefers-reduced-motion: reduce) {
  .live-dot { animation: none; }
  * { transition: none !important; }
  /* The marching dashes are deliberately NOT stopped here. Their speed is the
     reading -- it is how much is crossing that border -- so a stopped trail
     does not remove information, it states the wrong one. They are slowed to a
     quarter instead, in setDashPace, which is the only place that knows the
     pace to slow. */
}

/* The generation fleet. Area tracks installed capacity; the fill is the fuel's
   own colour from the mix, so a dot and its slice in the chart agree.

   The pale ring is what makes them read as markers rather than as map furniture:
   hydro's blue is within a shade of the 220 kV lines and of the import arrows,
   and unringed those dots disappeared into both. */
.plant-dot {
  stroke: rgba(232, 238, 251, .72);
  stroke-width: .8;
}
.marker-hit:hover + .plant-dot { stroke: #fff; }
.chart-hint[hidden] { display: none; }

/* --- Eclipse view ------------------------------------------------------- */
/* Darker ground than the other two maps on purpose: this one is about light
   going away, and the shadow bands only read against something dim. */
#mapEclipse { background: #050912; border-radius: inherit; }

/* Two panels side by side: the globe answers "where on Earth is the shadow",
   the map answers "how dark is it here". They cannot share a frame -- a flat
   map wide enough for both comes out twice as tall as it is wide. */
.eclipse-stage {
  position: absolute; inset: 8px;
  display: flex; gap: 10px; align-items: stretch;
}
.eclipse-globe {
  flex: 0 0 26%; max-width: 260px; min-width: 108px;
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: 6px;
}
.eclipse-globe canvas {
  display: block; border-radius: 50%;
  box-shadow: 0 0 22px rgba(80, 130, 210, .28), inset 0 0 20px rgba(0, 0, 0, .6);
}
.eclipse-globe-note {
  font-size: 11px; color: #8fa2c8; text-align: center; line-height: 1.25;
  font-variant-numeric: tabular-nums;
}
.eclipse-flat { position: relative; flex: 1 1 auto; min-width: 0; overflow: hidden;
                border-radius: 4px; }
.eclipse-flat canvas { position: absolute; inset: 0; width: 100%; height: 100%; display: block; }
/* Overrides `.map svg`, which insets by 10px and is meant for the other two
   maps. Here the svg has to land exactly on the canvas underneath it. */
#mapEclipse .eclipse-svg { position: absolute; inset: 0; width: 100%; height: 100%; display: block; }
/* Lengths below are viewBox units, driven by setInk() in eclipse_view.js so
   they render at a constant on-screen size whatever the panel width. The
   literals are only the fallback for the moment before it first runs. */
/* Borders only. The land itself is the satellite image on the canvas below,
   so these are the thin lines that say which country you are looking at. */
.eclipse-country { fill: none; stroke: rgba(190, 214, 255, .38);
                   stroke-width: var(--ecl-sw-country, 0.6px); }
.eclipse-dot { fill: #ffd479; stroke: #1a1200; stroke-width: var(--ecl-sw-country, 0.6px); }
.eclipse-dot.is-down { fill: #4d5a7a; }
.eclipse-label { fill: #eaf1ff; font-size: var(--ecl-fs-label, 11px); font-weight: 600;
                 paint-order: stroke; stroke: #0c1224;
                 stroke-width: var(--ecl-sw-texthalo, 2.5px); }
.eclipse-value { fill: #ffd479; font-size: var(--ecl-fs-value, 11px); font-weight: 700;
                 paint-order: stroke; stroke: #0c1224;
                 stroke-width: var(--ecl-sw-texthalo, 2.5px); }
.eclipse-caption { font-size: 14px; color: #cfdcf5; padding: 2px 4px; letter-spacing: 0.2px; }
.eclipse-caption b { color: #ffd479; font-variant-numeric: tabular-nums; }
.eclipse-caption span { color: #7d8db0; }
.eclipse-caption.is-waiting b { font-size: 17px; }
.eclipse-caption.is-live b { color: #ff9d5c; }
.eclipse-bar { display: flex; align-items: center; gap: 10px; padding: 2px 4px 4px; }
.eclipse-slider { flex: 1; accent-color: #ffd479; height: 4px; cursor: pointer; }
.eclipse-stamp { color: #cfdcf5; font-size: 13px; font-variant-numeric: tabular-nums; min-width: 46px; }
.eclipse-live { background: #1a2540; color: #7d8db0; border: 1px solid #2f4470;
                border-radius: 4px; padding: 3px 10px; font-size: 12px; cursor: pointer; }
.eclipse-live.is-on { background: #ffd479; color: #1a1200; border-color: #ffd479; font-weight: 700; }
.eclipse-wrap { display: flex; flex-direction: column; gap: 6px; width: 100%; }

/* The path of totality. Drawn under the shadow grid, so as the evening goes on
   the ribbon dims along with the ground it crosses -- which is the truth of it,
   since totality is exactly where the ground goes darkest. */
.eclipse-band { fill: rgba(255, 212, 121, .17); stroke: rgba(255, 212, 121, .5);
                stroke-width: var(--ecl-sw-band, .7px); pointer-events: none; }
.eclipse-centreline { fill: none; stroke: rgba(255, 212, 121, .75);
                      stroke-width: var(--ecl-sw-centre, 1px);
                      stroke-dasharray: var(--ecl-dash, 5px 4px); pointer-events: none; }

/* The day/night boundary: cool and dim on purpose.
   It was warm amber, which is the colour of the totality band and of the umbra
   ring, so it read as part of the eclipse rather than as the ordinary edge of
   night behind it. Nothing on this map should compete with the shadow except
   the shadow. Cool blue-grey puts it back where it belongs -- present enough to
   give the shading an edge, quiet enough that nobody mistakes it for the
   eclipse. */
.eclipse-dusk { pointer-events: none; }
/* One hairline. No bloom under it.
   There used to be a blurred stroke four times the width beneath this one, left
   over from when the line was gold. A blur spreads both ways, so the line was
   laying light on the daylight side as well as the night side -- a light sabre
   across the map, and the exact thing the shading is supposed to be the only
   source of. */
.eclipse-dusk-line { fill: none; stroke: rgba(150, 178, 224, .42);
                     stroke-width: calc(var(--ecl-sw-band, 1px) * 0.8); }
/* Set along the line, in the line's own colour. Letter-spaced and quiet: it is
   there to name a background, not to be read before the map is. */
.eclipse-dusk-label { fill: rgba(160, 186, 228, .62); font-size: var(--ecl-fs-dusk, 9.5px);
                      font-weight: 600; letter-spacing: .14em; paint-order: stroke;
                      stroke: rgba(6, 10, 22, .85);
                      stroke-width: var(--ecl-sw-texthalo, 2.5px); }

/* The umbra, which on this scale is a dot: a couple of hundred kilometres of
   ground against a continent. The halo is there to make it findable. */
.eclipse-umbra { pointer-events: none; }
.eclipse-umbra-halo { fill: none; stroke: #ffb347; stroke-width: var(--ecl-sw-umbrahalo, 7px);
                      opacity: .28; filter: blur(3px); }
.eclipse-umbra-spot { fill: #06080f; stroke: #ffd479; stroke-width: var(--ecl-sw-umbra, 1.2px); }

/* The pair of discs. Sized in em so it tracks the caption beside it. */
.eclipse-head { display: flex; align-items: center; gap: 12px; padding: 2px 4px; }
.eclipse-disc { width: 60px; height: 60px; flex: none; overflow: visible; }
/* The sky behind the pair, so a fully covered Sun still reads as a disc rather
   than as a hole in the page. */
.eclipse-sky { fill: #070b16; }
.eclipse-sun { fill: #ffd479; filter: drop-shadow(0 0 2px rgba(255, 212, 121, .9)); }
.eclipse-moon { fill: #05070e; }
/* No blur filter here. Lengths inside this svg are in disc radii, so a 2px
   blur is two solar radii -- it smeared the corona off the edge of the box and
   left the totality frames looking like a dead grey circle. */
.eclipse-corona { fill: none; stroke: #fffaf0; stroke-width: .2; opacity: 0; }
.eclipse-corona.is-outer { stroke: #ffe9b8; stroke-width: .55; }

/* The measured line. Sits under the legend because it is the slowest thing on
   the page: the geometry above is exact to the second, this arrives when the
   meters do. */
.eclipse-measured { display: flex; flex-wrap: wrap; align-items: baseline;
                    gap: 4px 12px; padding: 4px 4px 2px; font-size: 12px; }
.eclipse-measured[hidden] { display: none; }
.ecl-m-head { color: #7d8db0; }
.ecl-m-row { color: #cfdcf5; }
.ecl-m-row i { font-style: normal; color: #8fa2c8; margin-right: 5px; }
.ecl-m-row b { color: #ff9d5c; font-variant-numeric: tabular-nums; }
.ecl-m-age { color: #5d6b8a; }

.eclipse-legend { display: flex; flex-wrap: wrap; gap: 6px 16px; padding: 0 4px 2px;
                  font-size: 12px; color: #7d8db0; }
.eclipse-legend span { display: inline-flex; align-items: center; gap: 6px; }
.ecl-key { width: 16px; height: 9px; flex: none; border-radius: 2px; }
/* The scale swatch is the shading curve itself, over the same land colour the
   map uses, so the key is the drawing rather than a description of it. */
.ecl-key--scale { width: 46px; background:
  linear-gradient(90deg, #38558c 0%, #2c4470 30%, #1b2b48 60%, #0a1020 85%, #04060c 100%); }
.ecl-key--night { background: #1c2a4c; border: 1px solid #2f4470; }
.ecl-key--dusk { height: 0; border-top: 2px solid rgba(150, 178, 224, .55); }
.ecl-key--band { background: rgba(255, 212, 121, .22); border: 1px solid rgba(255, 212, 121, .55); }
.ecl-key--umbra { width: 10px; height: 10px; border-radius: 50%; background: #06080f;
                  border: 1.5px solid #ffd479; box-shadow: 0 0 5px rgba(255, 179, 71, .8); }

/* ---------------- the "i" beside every prosumer figure ---------------- */

/* A link rather than a button: the long explanation is a page, so it can be
   opened in a tab or sent to someone. The bubble is the short version. */
.info-dot {
  flex: none;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 14px;
  height: 14px;
  margin-left: 6px;
  border: 1px solid var(--ink-dim);
  border-radius: 50%;
  color: var(--ink-dim);
  font: italic 600 10px/1 system-ui, sans-serif;
  text-decoration: none;
  vertical-align: middle;
}
/* The circle is 14px because it sits inside lines of 12px type. The tap
   target around it is 28px, which is what a finger needs. */
.info-dot { position: relative; }
.info-dot::after { content: ''; position: absolute; inset: -7px; }
.info-dot:hover, .info-dot:focus-visible { color: var(--ink); border-color: var(--ink); }
.info-dot:focus-visible { outline: 2px solid var(--import); outline-offset: 2px; }
.info-dot[hidden] { display: none; }

/* The map legend lays its rows out in a column, so the dot needs a row of its
   own to sit on the same line as the toggle it belongs to. */
.legend-row { display: flex; align-items: center; }

/* Fixed and body-level, because two of these dots live inside KPI tiles that
   clip their overflow -- inside one, four lines of text came out as a stripe. */
.info-tip {
  position: fixed;
  z-index: 40;
  max-width: min(320px, 88vw);
  padding: 8px 11px;
  background: var(--panel-2);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  box-shadow: 0 8px 24px rgba(0, 0, 0, .45);
  font-size: 12px;
  line-height: 1.45;
  font-weight: 400;
  color: var(--ink-dim);
  text-transform: none;
  letter-spacing: 0;
  pointer-events: none;
}
.info-tip[hidden] { display: none; }

/* ---------------- the explanatory pages ---------------- */

.doc {
  max-width: 760px;
  /* Enough to carry the footer to the bottom of a desktop window: the article
     is shorter than the screen, and left alone it hung the footer mid-page. */
  min-height: calc(100vh - 190px);
  margin: 0 auto;
  padding: 22px 16px 40px;
}
.doc p { margin: 0 0 14px; font-size: 14.5px; line-height: 1.65; color: var(--ink-dim); }
.doc-lead { color: var(--ink); font-size: 16px; }
.doc h2 {
  margin: 26px 0 10px;
  font-size: 13px;
  font-weight: 600;
  letter-spacing: .08em;
  text-transform: uppercase;
  color: var(--ink-faint);
}
.doc ul { margin: 0 0 14px; padding-left: 20px; color: var(--ink-dim); font-size: 14.5px; line-height: 1.65; }
.doc li { margin-bottom: 4px; }
.doc-example {
  padding: 11px 13px;
  border-left: 2px solid var(--ink-faint);
  border-radius: 3px;
  background: var(--panel-2);
}
.doc-example b { color: var(--ink); font-weight: 600; }
.doc-note { color: var(--ink-faint); font-size: 13px; }
/* The switch between the site's two halves.
   
   It was a 12px line of dim text with an arrow -- the least prominent thing in
   the header, for the only control that moves between the two things this site
   is about. A segmented pair says both that there is a second section and which
   one you are looking at, which a one-way link cannot. */
.doc-switch {
  display: inline-flex;
  padding: 3px;
  gap: 2px;
  background: rgba(7, 14, 26, .9);
  border: 1px solid #2c4a75;
  border-radius: 9px;
}

.doc-tab {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  padding: 5px 11px;
  border-radius: 7px;
  font-size: 12.5px;
  font-weight: 600;
  color: var(--ink-faint);
  text-decoration: none;
  white-space: nowrap;
  transition: background .16s ease, color .16s ease;
}
.doc-tab svg { width: 13px; height: 13px; fill: currentColor; }
.doc-tab:hover { color: var(--ink); background: rgba(44, 74, 117, .35); }

/* The page you are on. Raised out of the strip rather than inverted out of it:
   two pale pills in the header read as buttons demanding to be pressed, and
   only one of them can be. This is a position indicator that happens to be
   clickable.
   
   The accent is the section's own and is already in the palette: the cool blue
   the 220 kV network is drawn in, and the amber the gas page uses for a store
   emptying. Cool for wires, warm for a flame -- which is the distinction the
   two icons are making anyway. */
.doc-tab.is-on {
  color: #9fd3f0;
  background: rgba(44, 74, 117, .55);
  box-shadow: inset 0 0 0 1px rgba(127, 196, 232, .45);
}
.doc-tab.is-on:hover { color: #c2e6fb; background: rgba(52, 86, 134, .65); }

body:has(.layout--gaz) .doc-tab.is-on {
  color: #f5b878;
  background: rgba(107, 71, 38, .5);
  box-shadow: inset 0 0 0 1px rgba(242, 153, 74, .45);
}
body:has(.layout--gaz) .doc-tab.is-on:hover {
  color: #ffd0a0;
  background: rgba(126, 84, 45, .6);
}

/* Narrower, not wordless. Hiding the labels left two glyphs 15px across, and
   the flame at that size reads as a droplet -- which points at water or oil,
   the two things it must not. The words are what carry this control; the icons
   only speed it up. */
/* On a phone the header carries the switch, the clock and the language pair in
   one row 390px wide, and all three at full size came to 410. The icons go, not
   the words: the words are what say which section is which, and a flame at
   11px reads as a droplet -- pointing at water or oil, the two things it must
   not. */
@media (max-width: 560px) {
  .doc-switch { padding: 2px; }
  .doc-tab { padding: 4px 7px; gap: 0; font-size: 11px; }
  .doc-tab svg { display: none; }
  /* 18px between three controls is 36px of a 390px row, and the row was 22px
     over. The gap is the cheapest of the three to give back: the switch and
     the clock both stop being readable before a gap stops being a gap. */
  .topbar-right { gap: 8px; }
}

/* ---------------- the rubric: what is out, and what was written ----------- */

/* Two headings inside one panel, so the second one needs the rule the panel's
   own head gets for free. Its top border is what separates the press from the
   plant list without spending a whole panel gap on it. */
.news-head { border-top: 1px solid var(--line-soft); margin-top: 2px; }
.news-head h2 a { color: inherit; text-decoration: none; }
.news-head h2 a:hover { color: var(--sold); }

.news-more {
  font-size: 11.5px;
  color: var(--ink-faint);
  text-decoration: none;
  white-space: nowrap;
}
.news-more:hover { color: var(--sold); }

.outages { list-style: none; margin: 0; padding: 6px 0 8px; }

.out-row {
  display: grid;
  grid-template-columns: 8px minmax(0, 1fr) auto;
  align-items: baseline;
  gap: 4px 9px;
  padding: 5px 16px;
}

.out-dot {
  width: 8px; height: 8px;
  border-radius: 50%;
  background: var(--idle);
  /* On the row's first text line rather than its box: the row is two lines and
     a dot centred on the box floats between them. */
  transform: translateY(-1px);
}

.out-name {
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  font-size: 13.5px;
}

.out-mw { font-size: 13.5px; font-weight: 700; white-space: nowrap; }

/* Under the name, across both text columns. */
.out-when {
  grid-column: 2 / -1;
  font-size: 11.5px;
  color: var(--ink-faint);
}
/* A unit that tripped is a different fact from one taken out for maintenance,
   and the list is read for the first. */
.out-row--forced .out-when { color: #e08a6a; }

.news { list-style: none; margin: 0; padding: 6px 0 8px; }

.news-row a {
  display: block;
  padding: 6px 16px;
  color: inherit;
  text-decoration: none;
}
.news-row a:hover { background: var(--panel-2); }

.news-title {
  display: block;
  font-size: 13px;
  line-height: 1.35;
  /* Three lines of a headline is enough to know whether to open it; the fourth
     is where a list of six turns into a page of its own. */
  display: -webkit-box;
  -webkit-line-clamp: 3;
  -webkit-box-orient: vertical;
  overflow: hidden;
}

.news-meta {
  display: block;
  margin-top: 2px;
  font-size: 11px;
  color: var(--ink-faint);
}

.news-none {
  margin: 0;
  padding: 6px 16px 10px;
  font-size: 12px;
  color: var(--ink-faint);
}

/* The rubric on its own page. The lists are the same ones the side panel
   builds, so only what the article context imposes on them is restated here:
   `.doc ul` sets a bullet and an indent, and it outranks a plain class. */
.doc--news h2 { display: flex; align-items: baseline; justify-content: space-between; gap: 12px; }
.doc-total {
  font-size: 15px;
  font-weight: 700;
  letter-spacing: 0;
  text-transform: none;
  color: var(--consum);
}
.doc-total--link { color: var(--ink-faint); font-weight: 400; font-size: 12px; text-decoration: none; }
.doc-total--link:hover { color: var(--sold); }
.doc-sub { font-size: 13px !important; color: var(--ink-faint) !important; }

.doc .outages, .doc .news {
  list-style: none;
  padding: 0;
  margin: 0 0 26px;
  border: 1px solid var(--line-soft);
  border-radius: var(--radius);
  background: var(--panel);
  overflow: hidden;
}
.doc .out-row, .doc .news-row { margin: 0; border-top: 1px solid var(--line-soft); }
.doc .out-row:first-child, .doc .news-row:first-child { border-top: 0; }
.doc .out-row { padding: 9px 14px; }
.doc .news-row a { padding: 10px 14px; }
/* On a page there is room for the whole headline, and cutting it there would
   be hiding the thing the page exists to show. */
.doc .news-title { font-size: 14px; -webkit-line-clamp: none; display: block; }

/* The third line of an outage row: how much of that fuel the country has.
   Muted even where the row above it is not -- a forced stop colours the kind
   of stop, not the arithmetic under it. */
.out-share {
  grid-column: 2 / -1;
  font-size: 11px;
  color: var(--ink-faint);
  opacity: .85;
}

/* The Romanian legend, folded into two columns.
   A single column of six rows stood 190px tall, and the taller it is the lower
   it reaches into the map -- past a point the drawing has to be shifted or
   shrunk to stay out from under it, which costs the reader more than the
   legend is worth. Paired, the same six rows come to about 115px and the map
   is left alone at the size most people are reading it on.
   Scoped by id: the European legend is the same class with entirely different
   children, and columns would tear it in half. */
#legendRo {
  display: grid;
  grid-template-columns: auto auto;
  align-items: center;
  gap: 5px 14px;
  padding: 9px 12px;
  font-size: 12.5px;
}
/* Same trap as the dusk row and the separator, one level up: an id sets
   display, and an id outranks `.legend[hidden]`, so the legend stayed on
   screen over the European map and the eclipse replay both. Anything that
   sets display on this element has to restate the hidden rule at its own
   weight. */
#legendRo[hidden] { display: none; }

/* The rows that are a sentence rather than a key stay full width. */
#legendRo > .legend-sep,
#legendRo > #roDuskRow,
#legendRo > .legend-row { grid-column: 1 / -1; }
#legendRo .legend-arrow { width: 22px; }
#legendRo .legend-wire { width: 22px; }

/* An author rule that sets `display` outranks the browser's own
   `[hidden] { display: none }`, whatever the specificity -- so every element
   that is hidden from JavaScript and styled by a class here has to say it
   again. This has now been found three separate ways: the legend rows, the
   Romanian legend itself, and the three below. The bar appeared over the
   Romanian map, the prosumer sub-line stayed after dark, and the "Analize"
   heading stood over an empty list. */
.eclipse-bar[hidden],
.panel-sub[hidden],
.panel-head[hidden] { display: none; }


/* ---------------- gas ---------------------------------------------------- */

/* The gas page borrows the dashboard wholesale -- .layout, .kpis, .band,
   .charts, .panel--map, .side -- so almost nothing is needed here. What was
   here before was a parallel set (.gkpis, .gk, .layout--gas) that drew the
   same tiles in the same shapes from a second stylesheet's worth of rules;
   two names for one thing is one of them waiting to drift. */

/* The grid's third row is sized by subtracting the fixed chrome from the
   viewport, and the band is part of that chrome. Gas puts three lines in each
   band slot where electricity puts two, so the strip measures 82px rather than
   46 -- and with the electricity figure the row was handed 36px it did not
   have, which is exactly how far the page overran one screen. */
.layout--gaz { --band-h: 82px; }

/* Bottom left, not top right. The shared position put the legend box straight
   over the Ungheni arrow and its figure -- the Moldovan crossing is in the
   top-right corner of this map, where the electricity map has empty Ukraine.
   The south-west corner is Serbia, and nothing is ever drawn there: the gas
   system has no Serbian interconnection at all. */
/* Bottom left, unlike every other legend on the site, and measured rather than
   chosen. This map carries a caption on both ends of every crossing, so it has
   more in its corners than the electricity map does: top right covers Ukraine's
   initials, its fill figure and the Ungheni caption. Bottom left is the only
   corner with nothing in it. */
#legendGas {
  top: auto;
  right: auto;
  left: 14px;
  bottom: 48px;
}

.kpi--gprod .kpi-label    { color: #5ec8d8; }
.kpi--gschimb .kpi-label  { color: var(--ink); }
.kpi--gdepozit .kpi-label { color: #a78bfa; }

.kpi-extra b { color: var(--ink-dim); font-weight: 600; }

.kpi--gdepozit .kpi-value em { font-style: normal; font-size: 13px; }
.kpi--gdepozit .kpi-value em.is-in  { color: #a78bfa; }
.kpi--gdepozit .kpi-value em.is-out { color: var(--consum); }

/* The band carries figures rather than a sentence on this page, so its numbers
   need to stand out of the line the way the price headline's do. */
.band-line b { color: var(--ink); font-weight: 700; }
.gas-when { font-style: normal; text-transform: none; letter-spacing: 0; color: var(--ink-dim); }
.gs-value.is-up   { color: var(--productie); }
.gs-value.is-down { color: var(--consum); }
.gk-flag { font-size: 11.5px; font-weight: 400; color: var(--frecventa); }
.gk-flag[hidden] { display: none; }

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

/* Reserved whether or not the pointer is over the plot: letting it collapse
   made the chart jump 18px as the mouse crossed it, which is worse than an
   empty line. */
.gc-readout {
  margin: 0;
  padding: 2px 14px 8px;
  min-height: 17px;
  font-size: 12.5px;
  color: var(--ink-faint);
}
.gc-readout b { color: var(--ink-dim); font-weight: 600; }

/* ---- the border map ---- */

.gm-svg { display: block; width: 100%; height: 100%; }

.gm-land { fill: var(--land); stroke: var(--land-line); stroke-width: 1; }
.gm-ro   { fill: var(--ro-land); stroke: var(--ro-line); stroke-width: 1.3; }

.gm-arrow--in  { stroke: var(--import); fill: var(--import); }
.gm-arrow--out { stroke: var(--export); fill: var(--export); }
.gm-head { stroke: none; }

/* A border that is open and carrying nothing, against one that has not
   reported yet. The filled dot is a measurement of zero; the ring is silence,
   and the two must not look alike. */
.gm-idle { fill: var(--idle); stroke: none; }
.gm-gap  { fill: none; stroke: var(--idle); stroke-width: 1.4; stroke-dasharray: 2 2; }

.gm-label { fill: var(--ink-dim); font-size: 12px; font-weight: 600; }
.gm-label--idle { fill: var(--ink-faint); font-weight: 400; }
.gm-value { font-size: 11.5px; }
.gm-value.is-in  { fill: var(--import); }
.gm-value.is-out { fill: var(--export); }

.legend-dot { width: 7px; height: 7px; border-radius: 50%; }
.legend-dot--idle { background: var(--idle); }
.legend-dot--gap { border: 1.4px dashed var(--idle); }

/* ---- storage panel ---- */

.fill-bar {
  height: 8px;
  margin: 10px 16px 4px;
  border-radius: 5px;
  background: #17293f;
  overflow: hidden;
}
.fill-bar span {
  display: block;
  height: 100%;
  width: 0;
  border-radius: 5px;
  background: linear-gradient(90deg, #7c5fd6, #a78bfa);
  transition: width .4s ease;
}

.panel-foot {
  margin: 8px 16px 12px;
  font-size: 12.5px;
  line-height: 1.55;
  color: var(--ink-faint);
}

/* ---- crossings table ---- */

.xtable td em { font-style: normal; color: var(--ink-faint); font-size: 12px; margin-left: 3px; }
.xtable td.is-import { color: var(--import); }
.xtable td.is-export { color: var(--export); }
.xtable td.is-idle   { color: var(--ink-faint); }

@media (max-width: 860px) {
  /* The map labels are placed in projection units and do not shrink with the
     viewBox, so on a phone they came out the size of the country. */
  .gm-label { font-size: 15px; }
  .gm-value { font-size: 14px; }
}

/* Not a quantity, so not in the tabular-figure column style the numbers get:
   a date sitting where a megawatt-hour figure normally sits reads as a very
   strange number until it is visibly a different kind of thing. */
.x-last { font-size: 12px; color: var(--ink-faint); font-variant-numeric: normal; }

/* The direction word is two short words and must stay on one line: wrapped, a
   quiet border read as "fără" over "flux", which looks like two facts. */
.xtable td.is-import, .xtable td.is-export, .xtable td.is-idle { white-space: nowrap; }

/* ---- underground stores ---- */

/* Empty tank, contents, rim. The contrast between the first two is what makes
   the level readable at a glance -- at .12 against .62 of the same hue the
   boundary was there and nobody saw it. */
.gm-store      { fill: rgba(12, 23, 39, .72); stroke: none; }
.gm-store-fill { fill: #a78bfa; fill-opacity: .85; stroke: none; pointer-events: none; }
.gm-store-line { stroke: #ede9fe; stroke-width: 1.4; pointer-events: none; }
.gm-store-ring { fill: none; stroke: #c4b5fd; stroke-width: 1.3; pointer-events: none; }

.stores { list-style: none; margin: 4px 0 0; padding: 0; }
.stores li {
  display: grid;
  grid-template-columns: 1fr 54px auto 32px 46px;
  align-items: center;
  gap: 8px;
  padding: 4px 16px;
  font-size: 13px;
  color: var(--ink-dim);
}
.st-name { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.st-bar { height: 7px; border-radius: 4px; background: #0c1727; box-shadow: inset 0 0 0 1px #1e3355; overflow: hidden; }
.st-bar i { display: block; height: 100%; border-radius: 3px; background: #a78bfa; }
.st-val { color: var(--ink); font-weight: 600; text-align: right; }
.st-val::after { content: ' TWh'; font-weight: 400; font-size: 11px; color: var(--ink-faint); }
.st-pct { text-align: right; color: var(--ink-faint); font-size: 12px; }

/* The legend swatch is the map's own drawing in miniature: an outline for the
   capacity with a smaller solid disc inside it for the stock. Two nested
   circles rather than a single dot, because the whole point of the marker is
   that it has two radii. */
.legend-store {
  width: 12px; height: 12px; border-radius: 50%;
  border: 1.2px solid #c4b5fd;
  background: linear-gradient(180deg, rgba(12,23,39,.72) 0 45%, #a78bfa 45%);
}

/* ---- the European gas map ---- */

/* Europe is nearly square and Romania is landscape. One aspect ratio for both
   letterboxes whichever view it was not written for. */
.panel--map.is-eu #gasMapEu { aspect-ratio: 1000 / 1030; }

.eu-land.is-stored { stroke: rgba(8, 16, 28, .55); }
.eu-land.is-stored:hover { stroke: var(--ink-dim); stroke-width: 1.6; }
.eu-land.is-picked { stroke: #ffe6a8; stroke-width: 1.8; }

/* Our own country, always outlined. White rather than a colour: every colour
   on this map already means a fill level, and a coloured outline would read as
   one more reading rather than as "you are here". */
.eu-land.is-home {
  stroke: #f4f8ff;
  stroke-width: 2;
  paint-order: stroke;
}
.eu-land.is-home.is-picked { stroke: #ffe6a8; }

/* Near white on purpose. The electricity map's gold arrow works over a price
   scale that is cold at the bottom; this scale is warm where a country is
   nearly empty, and a gold arrow over a country at 25 % disappears. White is
   the one value the storage ramp never reaches at either end. */
.eu-gasarrow {
  fill: #eef3ff;
  stroke: rgba(6, 13, 24, .75);
  stroke-width: 1.1;
  stroke-linejoin: round;
}

.eu-fillnum {
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  pointer-events: none;
}

#gasEuScale { display: flex; align-items: center; gap: 6px; }
#gasEuScale i {
  font-style: normal;
  font-size: 11px;
  color: var(--ink-faint);
  white-space: nowrap;
}
.eu-scale-bar { flex: 1; min-width: 54px; height: 9px; border-radius: 3px; }

/* ---- Romania against the rest of Europe ---- */

.eufill { list-style: none; margin: 6px 0 0; padding: 0; display: grid; gap: 4px; }
.eufill li {
  display: grid;
  grid-template-columns: 1fr 72px 34px;
  align-items: center;
  gap: 8px;
  font-size: 12.5px;
  color: var(--ink-faint);
}
.eufill .ef-name { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.eufill .ef-bar {
  height: 7px;
  border-radius: 3px;
  background: rgba(12, 23, 39, .72);
  overflow: hidden;
}
.eufill .ef-bar i { display: block; height: 100%; border-radius: 3px; }
.eufill .ef-val { text-align: right; font-variant-numeric: tabular-nums; }

/* Our own row, which is the reason the list exists. Marked by weight and a
   rule down the left rather than by colour: the bars already carry the scale
   and a second colour on one row would read as a different measurement. */
.eufill li.is-us {
  font-weight: 700;
  color: var(--ink-dim);
  margin-left: -6px;
  padding-left: 4px;
  border-left: 2px solid #a78bfa;
}

/* ---- how full a border ran ---- */

/* Under the quantity, not beside it: this is the same measurement seen a
   second way, and a fourth column pushed the quantity off the edge of a side
   panel that has no width to spare. */
.x-grad {
  display: block;
  margin-top: 1px;
  font-size: 11px;
  font-variant-numeric: tabular-nums;
  color: var(--ink-faint);
}
.x-grad.is-full { color: #f2994a; font-weight: 700; }

.gc-caption {
  margin: 0;
  padding: 0 14px 10px;
  font-size: 12px;
  color: var(--ink-faint);
}

/* The second line of the quantity header, naming what the small figure under
   each quantity is. Said once here rather than on every row, which is what
   pushed the column past the panel. */
.xtable .th-sub {
  display: block;
  font-style: normal;
  font-size: 10.5px;
  font-weight: 400;
  color: var(--ink-faint);
  opacity: .75;
}

/* The crossings table lives in a side column that is at its narrowest around
   1280px, where 16px of padding on both sides of all three cells spent 96px on
   gutters and pushed the table 22px past its panel. The outer edges keep their
   room; the two seams between columns give some of theirs back. Scoped to the
   gas page: the electricity page's tables sit in wider panels. */
.layout--gaz .xtable th,
.layout--gaz .xtable td { padding-left: 8px; padding-right: 8px; }
.layout--gaz .xtable th:first-child,
.layout--gaz .xtable td:first-child { padding-left: 14px; }
.layout--gaz .xtable th:last-child,
.layout--gaz .xtable td:last-child { padding-right: 14px; }

/* The quantity on a flow arrow. A plate rather than bare type: these sit over
   nineteen different fill colours, and text alone was legible on the greens
   and lost on the ambers. */
.eu-plate {
  fill: rgba(6, 13, 24, .82);
  stroke: rgba(219, 231, 255, .35);
  stroke-width: 0.8;
}
.eu-platetext {
  fill: #dbe7ff;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
}
.eu-flowlabel { pointer-events: none; }

/* What a store took in or gave out that gas day. The rate is about half a
   percent of the volume, so it cannot be drawn on the tank at any honest
   scale -- the map carries the direction as a chevron and the number lives
   here. */
.st-rate {
  text-align: right;
  font-size: 11.5px;
  font-variant-numeric: tabular-nums;
  color: var(--ink-faint);
}
.st-rate.is-in { color: #58c98a; }
.st-rate.is-out { color: #f2994a; }

/* An arrow that enters the tank or leaves it. Green going in, amber coming
   out -- and the direction is relative to the tank, which is the whole point:
   a mark above a container pointing up reads as gas escaping, however it is
   coloured. */
.gm-rate-stem { stroke-width: 2; stroke-linecap: round; }
.gm-rate-stem.is-in { stroke: #58c98a; }
.gm-rate-stem.is-out { stroke: #f2994a; }
.gm-rate-head { stroke: rgba(6, 13, 24, .55); stroke-width: 0.7; stroke-linejoin: round; }
.gm-rate-head.is-in { fill: #58c98a; }
.gm-rate-head.is-out { fill: #f2994a; }

.gm-rate-val {
  font-size: 11.5px;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  paint-order: stroke;
  stroke: rgba(6, 13, 24, .85);
  stroke-width: 3;
}
.gm-rate-val.is-in { fill: #58c98a; }
.gm-rate-val.is-out { fill: #f2994a; }

/* ---- the price tile ---- */

/* Five tiles on the gas page, not four. The price is a headline figure and
   belongs with the other four rather than in a panel below the fold. */
.layout--gaz .kpis { grid-template-columns: repeat(5, 1fr); }

.kpi--gpret .kpi-label em {
  font-style: normal;
  font-size: 10.5px;
  color: var(--ink-faint);
  opacity: .8;
}
#kPretDelta { font-style: normal; font-size: 12px; font-weight: 600; }
#kPretDelta.is-up { color: #f2994a; }
#kPretDelta.is-down { color: #58c98a; }

/* On a phone those five columns are five 70px slivers, and the labels ran
   straight through each other -- "Producție internă" over "Consum", "Depozite"
   over "TTF". The rule above is two classes deep, so the shared two-column
   rule in the 860px block never reached it; it has to be turned off here by
   name.

   Four tiles in the same 2x2 grid the electricity page uses, and the price
   underneath as a strip of its own: label on the left, figure on the right.
   It is the one tile that is a benchmark rather than a reading off our own
   system, so a row of its own states that rather than hiding it. */
@media (max-width: 860px) {
  .layout--gaz .kpis { grid-template-columns: repeat(2, 1fr); }
  /* Two columns, not a flex row. A flex line breaks on the items' own widths
     before it ever shrinks one of them, so at 360px the label and the figure
     came to 321px against 306px of room and the figure dropped under its own
     label. The label column takes what is left and wraps inside itself; the
     figure keeps its width at every width the page has. */
  .kpi--gpret {
    grid-column: 1 / -1;
    border-left: 0;
    display: grid;
    grid-template-columns: 1fr auto;
    align-items: baseline;
    column-gap: 12px;
  }
  .kpi--gpret .kpi-label { margin-bottom: 0; min-width: 0; }
  /* Under "TTF" rather than beside it, so the qualifier wraps as a phrase
     instead of splitting mid-way across the two lines. */
  .kpi--gpret .kpi-label em { display: block; }
  .kpi--gpret .kpi-value { justify-self: end; }
  /* A notch smaller than the four readings above it. This is a European
     settlement price, not a measurement off our own system, and at the same
     size it claimed the same standing -- and stopped fitting beside its own
     label on a 360px phone. */
  .kpi--gpret .kpi-value b { font-size: 21px; }
  /* The change rides on the figure's own line here. The shared mobile rule
     drops it below, which is right for a tall tile and wrong for a row: it
     cost this one a fourth line and left the figure alone in the middle. */
  .kpi--gpret .kpi-value em { flex-basis: auto; margin-top: 0; }
  /* The settlement date belongs under the label it qualifies, not squeezed
     between the label and the figure. */
  .kpi--gpret .kpi-extra { grid-column: 1 / -1; margin-top: 2px; }
}

/* ---- LNG arrivals ---- */

/* Violet, and doubled. LNG is a different kind of arrival -- by sea, from
   outside the continent -- and reading it as one more border flow is the
   mistake the map would otherwise invite.
   
   Violet because it is the one hue the storage ramp never touches: that ramp
   runs red, orange, yellow, green, teal, so the cyan this used to be was a near
   neighbour of both the pipeline arrows and a full country. */
.eu-lngarrow {
  fill: #b478f5;
  stroke: rgba(6, 13, 24, .75);
  stroke-width: 1.1;
  stroke-linejoin: round;
}
.eu-lngtail {
  fill: #b478f5;
  fill-opacity: .58;
  stroke: rgba(6, 13, 24, .6);
  stroke-width: 0.9;
  stroke-linejoin: round;
}

/* ---- where the gas comes from ---- */

.surse { list-style: none; margin: 6px 0 0; padding: 0; display: grid; gap: 4px; }
.surse li {
  display: grid;
  grid-template-columns: 1fr 64px 46px;
  align-items: center;
  gap: 8px;
  padding: 0 16px;
  font-size: 12.5px;
  color: var(--ink-faint);
}
.surse .su-name { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.surse .su-bar {
  height: 7px;
  border-radius: 3px;
  background: rgba(12, 23, 39, .72);
  overflow: hidden;
}
.surse .su-bar i { display: block; height: 100%; border-radius: 3px; background: #4aa8f0; }
.surse .su-val { text-align: right; font-variant-numeric: tabular-nums; }
/* LNG in the same blue it carries on the map, so the largest row here and the
   arrows out at sea are visibly the same fact. */
.surse li.is-lng .su-bar i { background: #b478f5; }
.surse li.is-lng { color: var(--ink-dim); font-weight: 600; }

/* ---- the neighbours on the Romanian map ---- */

.gm-neighbour {
  fill: var(--ink-faint);
  font-size: 13px;
  font-weight: 600;
  letter-spacing: .02em;
  paint-order: stroke;
  stroke: rgba(6, 13, 24, .85);
  stroke-width: 3;
}
.gm-neighbour-fill {
  font-size: 13px;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  paint-order: stroke;
  stroke: rgba(6, 13, 24, .85);
  stroke-width: 3;
}

/* The two kinds of arrival on the European map, side by side. Colour is the
   only thing separating a pipeline from a tanker there, so the legend has to
   carry it rather than describe it in words. */
.eu-legend-arrows { display: flex; flex-wrap: wrap; gap: 4px 14px; font-size: 12px; }
.eu-legend-arrows > span { display: inline-flex; align-items: center; gap: 5px; }
.legend-arrow--pipe path:first-child { stroke: #dbe7ff; }
.legend-arrow--pipe path:last-child { fill: #dbe7ff; stroke: none; }
.legend-arrow--lng path:first-child { stroke: #b478f5; }
.legend-arrow--lng path:last-child { fill: #b478f5; stroke: none; }
.legend-arrow--pipe path:first-child { stroke: #eef3ff; }
.legend-arrow--pipe path:last-child { fill: #eef3ff; stroke: none; }

/* The unit on a flow plate. Lighter than the figure so the quantity still
   leads and the unit reads as a qualifier rather than as more of the number. */
.eu-plateunit { fill: #9fb6d8; font-weight: 600; }

/* The two European panels move to the top of the column when the European map
   is the one on screen.
   
   They were sitting at y=1561 on a dashboard built to fit one screen, which is
   to say nobody found them: continental figures buried under Romanian ones.
   Reordered rather than hidden and shown, so nothing appears or disappears --
   the column simply leads with whatever the map is about. */
.side.is-eu .panel--eu { order: -1; }

/* ---- "more below" ---- */

/* Sticky at the foot of the scrollport rather than fixed to the panel, so it
   travels with the reader and comes to rest in its own place once the column
   has nothing left to show. Hidden by JS at the bottom, so it never points at
   nothing. */
.side-more {
  position: sticky;
  bottom: 2px;
  z-index: 3;
  align-self: center;
  flex: 0 0 auto;
  display: inline-flex;
  align-items: center;
  gap: 6px;
  margin: -6px 0 2px;
  padding: 5px 12px;
  font: inherit;
  font-size: 12px;
  font-weight: 600;
  color: var(--ink-dim);
  background: rgba(9, 18, 33, .92);
  border: 1px solid #2c4a75;
  border-radius: 999px;
  cursor: pointer;
  box-shadow: 0 4px 14px rgba(0, 0, 0, .45);
}
.side-more:hover { color: var(--ink); border-color: #3a5f92; }
.side-more svg { width: 12px; height: 8px; fill: none; stroke: currentColor; stroke-width: 2.2; stroke-linecap: round; stroke-linejoin: round; }

.legend-rate { width: 9px; height: 12px; fill: none; }
.legend-rate path:first-child { stroke: currentColor; stroke-width: 2; stroke-linecap: round; }
.legend-rate path:last-child { fill: currentColor; stroke: none; }
.legend-rate--in { color: #58c98a; }
.legend-rate--out { color: #f2994a; }

/* The unit on a storage rate, set smaller and quieter than the figure so the
   quantity still leads. */
.gm-rate-unit { font-size: 9.5px; font-weight: 600; opacity: .82; }

/* The neighbours' fill level on the gas map, in the slot the electricity map
   gives their price. Same type, same weight, same place -- the two maps differ
   in what they measure, not in how they are drawn. */
.gm-fill-value { text-anchor: middle; font-weight: 700; }

/* The percent sign on a country's fill figure: same ink, tucked in and set
   smaller so the number still leads. */
.eu-fillpct { opacity: .78; }

/* A picked country's own borders, coloured the way the Romanian map colours
   its arrows: blue coming in, green going out. Only when something is picked
   -- with the whole continent showing there is no "here" for in and out to be
   relative to. */
.eu-flowlabel.is-in .eu-plate { stroke: rgba(74, 168, 240, .75); }
.eu-flowlabel.is-in .eu-platetext { fill: #9fd0f8; }
.eu-flowlabel.is-in .eu-plateunit { fill: #7ab5e6; }
.eu-flowlabel.is-out .eu-plate { stroke: rgba(88, 201, 138, .75); }
.eu-flowlabel.is-out .eu-platetext { fill: #93e0b6; }
.eu-flowlabel.is-out .eu-plateunit { fill: #6fc79b; }

.eu-flow.is-in .eu-gasarrow { fill: #7ec2f5; }
.eu-flow.is-out .eu-gasarrow { fill: #7fdcaa; }

/* A picked country's own borders on the European power map, in the same two
   colours the Romanian map gives its arrows. */
.eu-flow.is-in .eu-plate { stroke: rgba(74, 168, 240, .8); }
.eu-flow.is-in .eu-flow-value { fill: #9fd0f8; }
.eu-flow.is-in .eu-leader { stroke: rgba(74, 168, 240, .55); }
.eu-flow.is-out .eu-plate { stroke: rgba(88, 201, 138, .8); }
.eu-flow.is-out .eu-flow-value { fill: #93e0b6; }
.eu-flow.is-out .eu-leader { stroke: rgba(88, 201, 138, .55); }

/* ---------- the offer comparator ---------- */

/* Wider than the reading pages. This one is a table, and a table squeezed into
   a column meant for prose wraps the supplier's name onto three lines. */
.doc--cmp { max-width: 940px; }

.cmp-bar {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 10px 18px;
  margin: 0 0 16px;
}

.cmp-pick { display: flex; align-items: center; gap: 9px; font-size: 14px; color: var(--ink-dim); }
.cmp-pick select {
  background: var(--panel-2);
  color: var(--ink);
  border: 1px solid var(--line);
  border-radius: 7px;
  padding: 7px 10px;
  font: inherit;
  font-size: 14px;
}
.cmp-pick select:focus-visible { outline: 2px solid var(--sold); outline-offset: 1px; }

.cmp-zone { font-size: 13px; color: var(--ink-faint); }

.cmp-table { width: 100%; border-collapse: collapse; font-size: 14.5px; }
.cmp-table th {
  text-align: left;
  padding: 8px 14px;
  border-bottom: 1px solid var(--line);
  color: var(--ink-faint);
  font-weight: 500;
  font-size: 12.5px;
  letter-spacing: .04em;
  text-transform: uppercase;
}
.cmp-table td { padding: 10px 14px; border-bottom: 1px solid rgba(30, 51, 85, .4); vertical-align: baseline; }
.cmp-table tr:last-child td { border-bottom: 0; }
.cmp-table a { color: var(--ink); text-decoration: none; border-bottom: 1px solid var(--line); }
.cmp-table a:hover { color: var(--sold); border-bottom-color: var(--sold); }
.cmp-table .num { text-align: right; white-space: nowrap; }

/* The row that matters, and the only one the eye should be able to compare
   down the column: same weight, same width per digit, no colour competing. */
.cmp-pret b { font-size: 17px; font-weight: 700; letter-spacing: -.2px; }
.cmp-pret i { font-style: normal; font-size: 12px; color: var(--ink-faint); margin-left: 4px; }
.cmp-table tr:first-child .cmp-pret b { color: var(--productie); }

.cmp-tip { font-size: 13px; color: var(--ink-dim); white-space: nowrap; }
.cmp-tip--dinamic { color: var(--sold); }
.cmp-tip--serviciu-universal { color: var(--frecventa); }

/* A dot, not a badge. That a figure came off a picture rather than out of the
   text is worth recording and is not worth a row of its own. */
.cmp-ocr { font-style: normal; color: var(--ink-faint); margin-left: 5px; cursor: help; }

.cmp-empty { color: var(--ink-faint); font-size: 14px; padding: 18px 0; }

.cmp-surse { display: flex; flex-wrap: wrap; gap: 6px 18px; margin: 0 0 12px; padding: 0; list-style: none; }
.cmp-surse a { color: var(--ink-dim); font-size: 13.5px; }

.cmp-links a { color: var(--sold); font-size: 14px; }

@media (max-width: 640px) {
  /* The offer's own name is the first thing to go: on a phone the reader is
     comparing suppliers and prices, and the document title is three words of
     marketing between them. It stays one tap away, in the link. */
  .cmp-table th:nth-child(3), .cmp-table td:nth-child(3) { display: none; }
  .cmp-table th, .cmp-table td { padding: 9px 8px; }
  .cmp-pret b { font-size: 16px; }
}
.cmp-pret em { font-style: normal; font-size: 13px; color: var(--ink-faint); }

/* The comparator's table is the one on the site that cannot be narrowed any
   further without dropping a column that carries meaning, so on a phone it
   scrolls sideways inside its own box rather than pushing the page out. */
.doc--cmp .table-scroll { overflow-x: auto; overflow-y: visible; }

@media (max-width: 640px) {
  .doc--cmp .cmp-table { font-size: 13.5px; }
  .doc--cmp .cmp-pret i { display: none; }
  .doc--cmp .cmp-bar { margin-bottom: 12px; }
  /* The unit belongs in the heading once it has left every row. */
  .doc--cmp .cmp-table th.num::after { content: ' (lei/kWh)'; text-transform: none; letter-spacing: 0; }
}

/* ---------- solar potential ---------- */

/* Two columns rather than the dashboard's three: there is one map and one set
   of numbers about it, and a third column would be filled for the sake of
   being filled. The map keeps the room, because reading where the country is
   bright is the part that needs pixels. */
.layout--solar {
  grid-template-columns: minmax(0, 1fr) clamp(340px, 27vw, 420px);
  /* A definite height, for the same reason the dashboard's third row has one:
     with 1fr the map's own aspect ratio decides the row and the panel grows
     past the fold, taking the legend and the readout with it. 150px is this
     page's chrome -- top bar, footer, the grid's padding -- measured. */
  grid-template-rows: minmax(0, clamp(420px, calc(100vh - 150px), 1100px));
}

/* The shared panel head paints its right-hand figure in the generation green,
   which is a colour with a meaning on this site and none on this page. */
.layout--solar .panel-total { color: var(--ink-dim); }
.layout--solar .panel-total b { font-size: 14px; font-weight: 600; }
/* The readout lives in the panel head now that there is no legend row under
   the map. It changes on every pointer move, so it is given room rather than
   allowed to reflow the heading beside it. */
.layout--solar .solar-mappanel .panel-total {
  flex: 0 1 auto; min-width: 0; text-align: right;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}

.solar-mappanel { display: flex; flex-direction: column; min-height: 0; overflow: hidden; }
.solar-mapwrap { position: relative; flex: 1 1 0; min-height: 0; display: flex; padding: 8px 12px 0; }
/* The map takes the gestures, the way a map does. Without this a pinch zooms
   the page and a drag scrolls it, and the two fingers never reach the map at
   all -- the panel has padding around it for anyone who wants to scroll past. */
.solar-map { width: 100%; height: 100%; display: block; touch-action: none; cursor: crosshair; }
.solar-map.is-zoomed { cursor: grab; }

/* Zoom in and the hairlines would thicken with everything else, until the
   county borders were roads. Keeping them at their stated width is the whole
   reason they are hairlines. */
.solar-county, .solar-border, .solar-picked {
  vector-effect: non-scaling-stroke;
}

/* Top left, opposite the zoom controls, which is where a map's search box is
   on every map anyone has used. */
/* Top left, opposite the zoom controls, which is where a map's search box is
   on every map anyone has used.

   In the page's own amber rather than the site's navy. Over satellite imagery
   a dark blue field on a dark blue border is chrome the eye slides off, and
   this is the one control that answers the question the reader arrived with --
   "where is my house". Warm on green reads first, and it is the same amber the
   Solar tab and the export button already carry, so it looks placed rather
   than painted. */
/* Top left, opposite the zoom controls, which is where a map's search box is
   on every map anyone has used.

   Light, and warm rather than white. Satellite imagery is dark and busy at
   every zoom -- green in the north, ploughed brown in the south, grey once
   there are roofs -- and the one thing none of it ever is, is pale. A light
   field is the only chrome that stays found without being fought for, which is
   what this control needs: it answers the question the reader arrived with. The
   cream keeps it in the page's amber rather than dropping a white browser
   widget on the map. */
.solar-find {
  position: absolute; top: 16px; left: 20px; z-index: 3; width: min(290px, 54%);
}
.solar-find > svg {
  position: absolute; left: 11px; top: 10px; width: 15px; height: 15px;
  fill: none; stroke: #a3701f; stroke-width: 1.8; stroke-linecap: round;
  pointer-events: none;
}
.solar-find input {
  width: 100%; padding: 8px 10px 8px 33px; font: inherit; font-size: 13.5px;
  color: #2b1d0b; background: #fdf6ea;
  border: 1px solid rgba(120, 80, 28, .3); border-radius: 5px;
  box-shadow: 0 2px 12px rgba(4, 8, 15, .45);
}
.solar-find input::placeholder { color: #8a7145; opacity: 1; }
.solar-find input:focus {
  outline: none; background: #fffdf8;
  border-color: #c98a3f;
  box-shadow: 0 2px 12px rgba(4, 8, 15, .45), 0 0 0 3px rgba(201, 138, 63, .38);
}
.solar-find input.is-loading { color: #8a7145; }

.solar-hits {
  position: absolute; left: 0; right: 0; top: calc(100% + 5px);
  max-height: 264px; overflow-y: auto;
  background: #fdf6ea;
  border: 1px solid rgba(120, 80, 28, .3); border-radius: 5px;
  box-shadow: 0 8px 20px rgba(4, 8, 15, .5);
}
.solar-hit {
  display: flex; align-items: baseline; gap: 8px; width: 100%;
  padding: 7px 11px; font: inherit; font-size: 13px; text-align: left;
  color: #2b1d0b; background: none; border: 0; cursor: pointer;
}
.solar-hit + .solar-hit { border-top: 1px solid rgba(120, 80, 28, .12); }
.solar-hit b { font-weight: 500; }
.solar-hit i { font-style: normal; font-size: 11.5px; color: #7d5f3a; }
.solar-hit.is-on, .solar-hit:hover { background: #f4dfbc; }

.solar-tools {
  position: absolute; top: 16px; right: 20px; z-index: 2;
  display: flex; flex-direction: column; gap: 4px;
}
.solar-tools button {
  display: flex; align-items: center; justify-content: center;
  width: 28px; height: 28px; padding: 0; cursor: pointer;
  color: var(--ink-dim); background: rgba(15, 26, 45, .82);
  border: 1px solid var(--line); border-radius: 4px;
}
.solar-tools button:hover { color: var(--ink); border-color: #2c4a75; }
.solar-tools svg {
  width: 16px; height: 16px; fill: none;
  stroke: currentColor; stroke-width: 1.6; stroke-linecap: round;
}

/* The pin is a symbol, not a thing on the ground: solar_view.js rescales it
   against the zoom so it stays the same size on screen. The ring is the panel's
   own colour, so the pin reads as sitting on the map rather than in it. */
/* The browser's own rule for [hidden] does not reach inside SVG: an element
   carrying the attribute still computes to display:inline and stays on screen.
   Everything the map and the legend put away -- the pin once it is taken off,
   the county outline, the mark that follows the pointer -- needs this to go. */
.solar-map [hidden] { display: none; }

/* The tiles are the ground once the reader is close enough for the raster to
   be lying to them. Nothing about them is interactive; the gestures belong to
   the map as a whole. */
.solar-tilelayer, .solar-lines { pointer-events: none; }
.solar-lines .solar-county { pointer-events: auto; }
/* Whatever is behind the tiles must not show through the seams between them. */
.solar-map.is-close { background: #0c1626; }

/* Owed to whoever took the pictures, so it appears with them and not before. */
.solar-credit {
  position: absolute; right: 20px; bottom: 6px; z-index: 2; margin: 0;
  padding: 2px 6px; border-radius: 3px;
  font-size: 10.5px; color: #cfd8e8; background: rgba(7, 13, 24, .66);
  opacity: 0; transition: opacity .25s; pointer-events: none;
}
.solar-mapwrap.is-close .solar-credit { opacity: 1; }

.solar-pin { pointer-events: none; }
.solar-pin-body { fill: #fff3dd; stroke: #3a1c04; stroke-width: 1.2; }
.solar-pin-eye { fill: #9a3c00; }

/* Everything the map draws now sits over a photograph, so the outlines are
   light with their own shadow rather than dark hairlines. Over farmland a thin
   dark line disappears; over a city it reads as a road. */
.solar-county {
  fill: rgba(0, 0, 0, 0); stroke: rgba(255, 255, 255, .34); stroke-width: 1.1;
}
.solar-county:hover { stroke: rgba(255, 255, 255, .8); stroke-width: 1.8; }
.solar-border { fill: none; stroke: rgba(255, 255, 255, .72); stroke-width: 1.8; }

/* Names over a photograph: light, with a dark edge cut behind them so they
   survive both a snow-covered ridge and a ploughed field. paint-order puts the
   stroke under the fill, which is what makes it an outline and not a bold. */
.solar-names {
  font-family: system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
  font-weight: 600; letter-spacing: .02em;
  fill: #ffffff; stroke: rgba(6, 11, 20, .78); stroke-width: 3px;
  paint-order: stroke; vector-effect: non-scaling-stroke;
  pointer-events: none;
}

/* Not Romania. Dimmed rather than hidden, so the reader can still see what is
   over the border and still be in no doubt which country the page is about. */
.solar-outside { fill: rgba(6, 11, 20, .62); stroke: none; pointer-events: none; }

/* The chosen county: a bright outline, not a fill. Filling it would hide the
   very thing the reader came to see inside it. */
.solar-picked {
  fill: none; stroke: #ffffff; stroke-width: 2.6;
  paint-order: stroke; pointer-events: none;
}

.solar-side { display: flex; flex-direction: column; gap: 14px; min-width: 0; overflow-y: auto; }

/* One number the page exists to produce, at the size that says so. */
.solar-hero { padding: 14px 16px 4px; }
.solar-hero b { font-size: 34px; font-weight: 700; color: #ffebd5; }
.solar-hero i { font-style: normal; font-size: 13px; color: var(--ink-dim); margin-left: 4px; }
.solar-hero em {
  display: block; margin-top: 3px; font-style: normal;
  font-size: 12.5px; color: var(--ink-faint);
}
/* The same answer in money, one step down from the kWh it is made of. */
.solar-money { display: block; margin-top: 8px; }
.solar-money b { font-size: 20px; font-weight: 600; color: var(--ink); }

.solar-fields { padding: 6px 16px 0; display: grid; gap: 10px; }
.solar-fields label {
  display: grid; grid-template-columns: 1fr minmax(0, 130px) 46px;
  align-items: center; gap: 10px; font-size: 13.5px; color: var(--ink-dim);
}
.solar-fields i { font-style: normal; font-size: 12.5px; color: var(--ink-faint); text-align: right; white-space: nowrap; }
.solar-fields i b { color: var(--ink); font-weight: 600; }
.solar-fields input[type=number], .solar-fields select {
  background: var(--panel-2); border: 1px solid var(--line); border-radius: 4px;
  color: var(--ink); font: inherit; padding: 4px 7px; width: 100%;
}
.solar-fields input::placeholder { color: var(--ink-faint); }
.solar-fields select { cursor: pointer; }
.solar-fields input[type=range] { width: 100%; accent-color: #da9d51; }

.solar-reset {
  margin: 12px 16px 0; padding: 6px 10px; font: inherit; font-size: 13px;
  color: var(--ink-dim); background: var(--panel-2);
  border: 1px solid var(--line); border-radius: 4px; cursor: pointer;
}
.solar-reset:hover { color: var(--ink); border-color: #2c4a75; }

.solar-acts { display: flex; flex-wrap: wrap; gap: 8px; margin: 12px 16px 0; }
.solar-acts .solar-reset { margin: 0; }
/* The one button on the page that produces something to keep, so it carries
   the page's own colour rather than the neutral of the controls beside it. */
.solar-export { display: inline-flex; align-items: center; gap: 6px; color: #e9b67b; }
.solar-export:hover { color: #ffebd5; border-color: #6b4a22; }
.solar-export[disabled] { opacity: .55; cursor: default; }
.solar-export svg {
  width: 13px; height: 13px; fill: none;
  stroke: currentColor; stroke-width: 1.6; stroke-linecap: round; stroke-linejoin: round;
}

.solar-months { padding: 14px 16px 16px; }
.solar-months h3 {
  display: inline; margin: 0; font-size: 13px; font-weight: 600;
  letter-spacing: .04em; text-transform: uppercase; color: var(--ink-faint);
}
/* The hovered month is written next to the heading rather than floating over
   bars this narrow, where a tooltip would cover its own neighbours. */
.solar-monthread { margin-left: 8px; font-size: 12.5px; color: var(--ink-dim); }
.solar-bars-svg { width: 100%; height: auto; margin-top: 8px; display: block; }
.solar-bar { fill: rgba(218, 157, 81, .45); }
.solar-bar.is-peak { fill: rgba(255, 235, 213, .75); }
.solar-bar:hover { fill: rgba(255, 235, 213, .9); }
.solar-bar-label { fill: var(--ink-faint); font-size: 8.5px; }
.solar-bar-value { fill: var(--ink-dim); font-size: 9px; font-weight: 600; }

.solar-note { padding: 14px 16px; }
.solar-note p { margin: 0 0 10px; font-size: 13px; line-height: 1.6; color: var(--ink-dim); }
.solar-note p:last-child { margin-bottom: 0; }

@media (max-width: 1180px) {
  .layout--solar { grid-template-columns: minmax(0, 1fr); grid-template-rows: auto auto; }
  /* Stacked, the map gets the box its own shape asks for. A height in vh gave
     it a tall box to letterbox inside, and the empty band read as a gap in the
     page rather than as margin around a map. */
  /* flex:none, or the aspect ratio never gets a say. Stacked, the panel has no
     height of its own to hand out, so the flex-basis of 0 that the desktop row
     depends on resolves the map to nothing and grow has no room to give it
     back -- the map came out zero pixels tall on every phone. */
  .solar-mapwrap { flex: none; aspect-ratio: 1.42; padding-bottom: 8px; }
  .solar-side { overflow: visible; }
}

.solar-check-text {
  margin: 6px 16px 0; font-size: 12.5px; line-height: 1.6; color: var(--ink-dim);
}
.solar-check-h {
  margin: 14px 16px 0; font-size: 12px; font-weight: 600;
  letter-spacing: .04em; text-transform: uppercase; color: var(--ink-faint);
}
.solar-check-list { margin: 6px 0 16px; padding: 0 16px; list-style: none; }
.solar-check-list li {
  display: flex; justify-content: space-between; gap: 12px;
  padding: 4px 0; font-size: 13px; color: var(--ink-dim);
  border-bottom: 1px solid var(--line-soft);
}
.solar-check-list li:last-child { border-bottom: 0; }
.solar-check-list b { font-weight: 600; }
/* Neither direction is a fault, so neither gets a red. Above the national
   ratio is the warmer end of the page's own ramp, below it is the cooler ink. */
.solar-check-list b.is-over { color: #ffebd5; }
.solar-check-list b.is-under { color: var(--ink-faint); }
.solar-check-more { margin: 10px 16px 0; font-size: 12.5px; }
.solar-check-more a { color: #e9b67b; text-decoration: none; }
.solar-check-more a:hover { text-decoration: underline; }

/* The forecast check on the prosumer page. A doc page, so it reads as prose
   with one figure in it, not as a dashboard panel. */
.doc-check {
  max-width: 760px; margin: 4px auto 26px; padding: 0 22px;
}
.doc-check h2 {
  margin: 0 0 12px; font-size: 19px; font-weight: 600;
  padding-top: 18px; border-top: 1px solid var(--line-soft);
}
.doc-check h3 {
  margin: 18px 0 6px; font-size: 12px; font-weight: 600;
  letter-spacing: .04em; text-transform: uppercase; color: var(--ink-faint);
}
.doc-check p { margin: 0 0 14px; font-size: 14.5px; line-height: 1.65; color: var(--ink-dim); }
.doc-check-figure { margin-bottom: 2px !important; }
.doc-check-figure b { font-size: 32px; font-weight: 700; color: #ffebd5; margin-right: 6px; }
.doc-check-pair { font-size: 13px !important; color: var(--ink-faint) !important; }
.doc-check-list { margin: 0 0 14px; padding: 0; list-style: none; font-size: 14px; color: var(--ink-dim); }
.doc-check-list li { padding: 4px 0; border-bottom: 1px solid var(--line-soft); }
.doc-check-list li:last-child { border-bottom: 0; }

/* The calculator's own accent in the section switch. Only the current page's
   tab is ever coloured, so this never sits next to the gas amber it is close
   to -- the two are alternatives, not neighbours. */
body:has(.layout--solar) .doc-tab.is-on {
  color: #ffd9a3;
  background: rgba(102, 66, 24, .5);
  box-shadow: inset 0 0 0 1px rgba(255, 199, 122, .45);
}
body:has(.layout--solar) .doc-tab.is-on:hover {
  color: #ffe9cd;
  background: rgba(122, 80, 32, .6);
}
.solar-spread {
  margin: 10px 16px 0; font-size: 12px; line-height: 1.55; color: var(--ink-faint);
}
.solar-spread:empty { display: none; }
