/* ==========================================================================
   SA SOLAR — effects.css
   The five signature systems.
     01 THE ARRAY      · live 3D tracker plant behind the hero
     02 THE SURVEY     · measurement-line reveal + telemetry readouts
     03 THE SECTION    · exploded cross-section of an installation
     04 THE INSTRUMENT · live payback and yield model
     05 THE IRRADIANCE · South African resource map
   ========================================================================== */

/* ==========================================================================
   01 · THE ARRAY — hero
   ========================================================================== */
.hero {
  position: relative;
  min-height: min(100svh, 900px);
  display: flex;
  flex-direction: column;
  justify-content: flex-end;
  padding-top: calc(var(--header-h) + 40px);
  padding-bottom: 0;
  overflow: hidden;
  background: var(--bg);
}
.hero--short { min-height: min(78svh, 720px); }

.hero__canvas {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  z-index: 0;
}

/* Brand hero treatment: white type stays legible over a 30–50% dark overlay. */
.hero__scrim {
  position: absolute;
  inset: 0;
  z-index: 1;
  background: rgba(0, 0, 0, 0.44);
  pointer-events: none;
}

.hero__inner {
  position: relative;
  z-index: 2;
  width: 100%;
  display: flex;
  flex-direction: column;
  gap: clamp(28px, 4vw, 48px);
  padding-bottom: clamp(28px, 4vw, 52px);
}

.hero__eyebrow { display: flex; align-items: center; gap: 14px; margin-bottom: 26px; }
.hero__eyebrow::before {
  content: '';
  width: 34px; height: 1px; background: var(--olive-line);
}

.hero__title { max-width: 19ch; margin-bottom: 26px; }
.hero__lead { max-width: 56ch; color: #C8C8C8; margin-bottom: 34px; }

/* --- Reticles: the frame is a survey viewport, not a photograph ---------- */
.hero__reticle {
  position: absolute;
  z-index: 2;
  width: 26px; height: 26px;
  border: 1px solid var(--olive-line);
  opacity: 0.5;
  pointer-events: none;
}
.hero__reticle--tl { top: calc(var(--header-h) + 26px); left: var(--gutter); border-right: 0; border-bottom: 0; }
.hero__reticle--tr { top: calc(var(--header-h) + 26px); right: var(--gutter); border-left: 0; border-bottom: 0; }
@media (max-width: 760px) { .hero__reticle { display: none; } }

/* ==========================================================================
   02 · THE SURVEY — telemetry HUD
   Every figure here is produced by the simulation in array.js.
   ========================================================================== */
.hud {
  position: relative;
  z-index: 2;
  border-top: 1px solid var(--border);
  background: rgba(0, 0, 0, 0.5);
  backdrop-filter: blur(8px);
  -webkit-backdrop-filter: blur(8px);
}
.hud__inner {
  display: grid;
  grid-template-columns: auto repeat(4, minmax(0, 1fr));
  align-items: stretch;
}
.hud__tag {
  display: flex; align-items: center; gap: 9px;
  padding: 16px clamp(16px, 2vw, 28px) 16px 0;
  border-right: 1px solid var(--border);
  white-space: nowrap;
}
.hud__pip {
  width: 6px; height: 6px; border-radius: 50%;
  background: var(--olive-ink);
  animation: hudPip 2.4s var(--ease-in-out) infinite;
}
@keyframes hudPip { 0%, 100% { opacity: 1; } 50% { opacity: 0.25; } }

.hud__cell {
  padding: 14px clamp(12px, 1.8vw, 24px);
  border-right: 1px solid var(--border);
  display: flex; flex-direction: column; gap: 5px;
  min-width: 0;
}
.hud__cell:last-child { border-right: 0; }
.hud__k {
  font-size: 0.6875rem; font-weight: 500; letter-spacing: 0.1em;
  text-transform: uppercase; color: var(--muted);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.hud__v {
  font-size: clamp(0.9375rem, 0.85rem + 0.4vw, 1.125rem);
  font-weight: 600;
  font-variant-numeric: tabular-nums;
  letter-spacing: -0.01em;
  white-space: nowrap;
}
.hud__v--accent { color: var(--olive-ink); }

/* Tracking-efficiency bar — driven by --v from the simulation */
.hud__bar {
  position: relative;
  height: 2px; width: 100%;
  background: var(--border);
  margin-top: 4px;
  overflow: hidden;
}
.hud__bar::after {
  content: '';
  position: absolute; inset: 0 auto 0 0;
  width: var(--v, 0%);
  background: var(--olive-ink);
  transition: width 0.24s linear;
}

@media (max-width: 900px) {
  .hud__inner { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .hud__tag { grid-column: 1 / -1; border-right: 0; border-bottom: 1px solid var(--border); padding-left: 0; }
  .hud__cell:nth-child(odd) { border-right: 1px solid var(--border); }
  .hud__cell { border-bottom: 1px solid var(--border); }
}

/* ==========================================================================
   02 · THE SURVEY — the measurement pass
   A line crosses each block; the content behind it resolves in reading
   order. Geometry first, then figures, then type.
   ========================================================================== */
[data-survey] { position: relative; }

[data-survey].is-scanning::after {
  content: '';
  position: absolute;
  left: 0; right: 0; top: 0;
  height: 1px;
  background: var(--olive-ink);
  opacity: 0.55;
  pointer-events: none;
  z-index: 5;
  animation: surveyPass 0.82s cubic-bezier(0.4, 0, 0.2, 1) forwards;
}
@keyframes surveyPass {
  0%   { top: 0;    opacity: 0; }
  12%  {             opacity: 0.6; }
  88%  {             opacity: 0.6; }
  100% { top: 100%; opacity: 0; }
}

/* Gated on the `js` class set synchronously in <head>. With scripting off,
   nothing is ever hidden — the survey pass is an enhancement, not a
   prerequisite for reading the page. */
.js [data-survey-item] {
  opacity: 0;
  transform: translateY(16px);
  filter: blur(5px);
  transition:
    opacity 0.62s var(--ease) calc(var(--i, 0) * 62ms),
    transform 0.62s var(--ease) calc(var(--i, 0) * 62ms),
    filter 0.62s var(--ease) calc(var(--i, 0) * 62ms);
  will-change: opacity, transform, filter;
}
[data-survey].is-resolved [data-survey-item] {
  opacity: 1;
  transform: none;
  filter: none;
}
[data-survey].is-resolved [data-survey-item] { will-change: auto; }

@media (prefers-reduced-motion: reduce) {
  [data-survey-item] { opacity: 1; transform: none; filter: none; }
  [data-survey].is-scanning::after { display: none; }
}

/* ==========================================================================
   03 · THE SECTION — exploded cross-section
   ========================================================================== */
.xsec {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 0.82fr);
  gap: clamp(28px, 4vw, 64px);
  align-items: start;
}
.xsec__stage {
  position: relative;
  aspect-ratio: 4 / 5;
  border: 1px solid var(--border);
  border-radius: var(--r-card);
  background: var(--bg);
  overflow: hidden;
}
.section--surface .xsec__stage { background: #060606; }
.xsec__svg { width: 100%; height: 100%; display: block; }

.xsec__hint {
  position: absolute; left: 18px; bottom: 16px;
  font-size: var(--t-micro); letter-spacing: 0.08em; text-transform: uppercase;
  color: var(--muted);
  display: flex; align-items: center; gap: 8px;
  pointer-events: none;
}
.xsec__hint::before {
  content: ''; width: 16px; height: 1px; background: var(--olive-line);
}

/* Layer legend / readout */
.xsec__panel { position: sticky; top: calc(var(--header-h) + 32px); }
.xsec__list { border-top: 1px solid var(--border); }
.xsec__item {
  display: grid;
  grid-template-columns: 34px minmax(0, 1fr);
  gap: 16px;
  align-items: start;
  width: 100%;
  text-align: left;
  padding: 17px 6px;
  border-bottom: 1px solid var(--border);
  cursor: pointer;
  transition: background-color 0.3s var(--ease), padding-inline 0.3s var(--ease);
}
.xsec__item:hover { background: var(--surface-2); }
.xsec__item[aria-current='true'] { background: var(--surface-2); padding-inline: 14px 6px; }
.xsec__num {
  font-size: var(--t-micro); font-weight: 500; letter-spacing: 0.1em;
  color: var(--muted); font-variant-numeric: tabular-nums; padding-top: 3px;
  transition: color 0.3s var(--ease);
}
.xsec__item[aria-current='true'] .xsec__num { color: var(--olive-ink); }
.xsec__name { display: block; font-size: var(--t-small); font-weight: 600; }
/* Must be a block — max-height has no effect on an inline box, which would
   leave every collapsed row holding the height of its hidden specification. */
.xsec__spec {
  display: block;
  font-size: var(--t-micro); color: var(--text-2); line-height: 1.55;
  max-height: 0; overflow: hidden;
  transition: max-height 0.42s var(--ease), margin-top 0.42s var(--ease), opacity 0.3s var(--ease);
  opacity: 0;
}
.xsec__item[aria-current='true'] .xsec__spec { max-height: 8em; opacity: 1; margin-top: 3px; }

/* --- the drawing itself --- */
.xs-layer { transition: opacity 0.36s var(--ease); }
.xs-layer.is-dim { opacity: 0.22; }

.xs-top   { fill: #12150E; stroke: #333A2B; stroke-width: 1; transition: fill 0.34s var(--ease), stroke 0.34s var(--ease); }
.xs-face  { stroke: #2A2A2A; stroke-width: 1; transition: fill 0.34s var(--ease), stroke 0.34s var(--ease); }
.xs-face--l { fill: #0B0D08; }
.xs-face--r { fill: #070804; }

.xs-rule line { stroke: #262C1D; stroke-width: 1; transition: stroke 0.34s var(--ease); }

.xs-layer.is-active .xs-top,
.xs-layer.is-hover  .xs-top   { fill: #1E2417; stroke: var(--olive-ink); }
.xs-layer.is-active .xs-face,
.xs-layer.is-hover  .xs-face  { stroke: var(--olive-line); }
.xs-layer.is-active .xs-rule line,
.xs-layer.is-hover  .xs-rule line { stroke: var(--olive-line); }

.xs-lead { opacity: calc(var(--lead, 0) * 0.6); transition: opacity 0.3s var(--ease); }
.xs-lead line { stroke: var(--border); stroke-width: 1; stroke-dasharray: 2 3; }
.xs-lead circle { fill: var(--muted); }
.xs-num { fill: var(--muted); font-size: 11px; font-weight: 500; letter-spacing: 0.08em; font-family: inherit; }

.xs-layer.is-active .xs-lead { opacity: calc(var(--lead, 0) * 1); }
.xs-layer.is-active .xs-lead line { stroke: var(--olive-line); stroke-dasharray: none; }
.xs-layer.is-active .xs-lead circle,
.xs-layer.is-active .xs-num { fill: var(--olive-ink); }

.xs-riser { stroke: var(--olive-line); stroke-width: 1; stroke-dasharray: 3 5; transition: opacity 0.3s var(--ease); }

@media (max-width: 900px) {
  .xsec { grid-template-columns: minmax(0, 1fr); }
  .xsec__stage { aspect-ratio: 1 / 1; max-height: none; }
  .xsec__panel { position: static; }
}

/* ==========================================================================
   04 · THE INSTRUMENT — payback and yield model
   ========================================================================== */
.instr {
  border: 1px solid var(--border);
  border-radius: var(--r-card);
  background: var(--surface);
  overflow: hidden;
}
.section--surface .instr { background: #080808; }

.instr__head {
  display: flex; flex-wrap: wrap; gap: 14px 24px;
  align-items: center; justify-content: space-between;
  padding: 20px clamp(20px, 2.6vw, 34px);
  border-bottom: 1px solid var(--border);
}
.instr__title { font-size: var(--t-label); font-weight: 600; letter-spacing: 0.06em; text-transform: uppercase; }
.instr__body {
  display: grid;
  grid-template-columns: minmax(0, 344px) minmax(0, 1fr);
  align-items: stretch;
}
.instr__controls {
  padding: clamp(22px, 2.6vw, 32px);
  border-right: 1px solid var(--border);
  display: flex; flex-direction: column; gap: 26px;
}
.instr__ctl { display: flex; flex-direction: column; gap: 11px; }
.instr__ctl-head { display: flex; justify-content: space-between; align-items: baseline; gap: 12px; }
.instr__ctl-head > .label { min-width: 0; }
.instr__ctl-val { font-size: var(--t-small); font-weight: 600; font-variant-numeric: tabular-nums; white-space: nowrap; }
.instr__ctl-val .u { color: var(--text-2); font-weight: 400; }

.instr__chart { position: relative; min-height: 380px; padding: clamp(18px, 2.4vw, 28px); }
.instr__chart svg { width: 100%; height: 100%; display: block; overflow: visible; }

.instr__out {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
  border-top: 1px solid var(--border);
}
.instr__outcell {
  padding: 20px clamp(18px, 2.4vw, 30px);
  border-right: 1px solid var(--border);
  display: flex; flex-direction: column; gap: 7px;
}
.instr__outcell:last-child { border-right: 0; }
.instr__outk { font-size: var(--t-micro); letter-spacing: 0.09em; text-transform: uppercase; color: var(--muted); }
.instr__outv {
  font-size: clamp(1.375rem, 1.1rem + 1vw, 1.875rem);
  text-wrap: nowrap;
  font-weight: 600; letter-spacing: -0.025em; line-height: 1;
  font-variant-numeric: tabular-nums;
}
.instr__outv .u { font-size: 0.55em; color: var(--text-2); font-weight: 400; margin-left: 4px; letter-spacing: 0; }
.instr__outv--accent { color: var(--olive-ink); }

/* chart primitives */
.instr .ax { stroke: var(--border); stroke-width: 1; }
.instr .grid-l { stroke: #1A1A1A; stroke-width: 1; }
.instr .tick { fill: var(--muted); font-size: 11px; font-weight: 500; letter-spacing: 0.04em; }
.instr .ser-grid { fill: none; stroke: #6B6B6B; stroke-width: 1.75; }
.instr .ser-solar { fill: none; stroke: var(--olive-ink); stroke-width: 2.25; }
.instr .ser-fill { fill: var(--olive-glow); }
.instr .cross { stroke: var(--olive-ink); stroke-width: 1; stroke-dasharray: 3 4; }
.instr .cross-dot { fill: var(--olive-ink); }
.instr .flag-txt { fill: #fff; font-size: 12px; font-weight: 600; }
.instr .legend-txt { fill: var(--text-2); font-size: 12px; font-weight: 500; }

.instr__note {
  padding: 14px clamp(20px, 2.6vw, 34px) 20px;
  border-top: 1px solid var(--border);
  font-size: var(--t-micro);
  color: var(--muted);
  line-height: 1.6;
}

@media (max-width: 900px) {
  .instr__body { grid-template-columns: minmax(0, 1fr); }
  .instr__controls { border-right: 0; border-bottom: 1px solid var(--border); }
  .instr__chart { min-height: 320px; }
}

/* ==========================================================================
   05 · THE IRRADIANCE — resource map
   ========================================================================== */
.irr {
  display: grid;
  grid-template-columns: minmax(0, 1.25fr) minmax(0, 0.75fr);
  gap: clamp(28px, 4vw, 60px);
  align-items: center;
}
.irr__stage {
  position: relative;
  border: 1px solid var(--border);
  border-radius: var(--r-card);
  background: var(--bg);
  padding: clamp(14px, 2vw, 26px);
}
.section--surface .irr__stage { background: #080808; }
.irr__svg { width: 100%; height: auto; display: block; overflow: visible; }

/* District hairlines are drawn dark, so the map keeps its survey texture
   while colour still reads at province level. */
.irr .prov {
  stroke: #0B0D07;
  stroke-width: 0.8;
  transition: fill 0.32s var(--ease), stroke 0.32s var(--ease), filter 0.32s var(--ease);
}
.irr .prov-g { cursor: pointer; outline: none; }
.irr .prov-g:focus-visible .prov { stroke: #fff; }
.irr .prov.is-active { stroke: var(--olive-ink); stroke-width: 1.1; filter: brightness(1.22); }

.irr .prov-label {
  fill: rgba(255, 255, 255, 0.42);
  font-size: 10px; font-weight: 600; letter-spacing: 0.08em;
  pointer-events: none;
  transition: fill 0.3s var(--ease);
}
.irr .prov-label.is-active { fill: #fff; }

.irr .site { fill: none; stroke: var(--olive-ink); stroke-width: 1.2; }
.irr .site-core { fill: var(--olive-ink); }
.irr .site-ring { animation: sitePulse 3.4s var(--ease-in-out) infinite; transform-origin: center; transform-box: fill-box; }
@keyframes sitePulse {
  0%   { r: 3;  opacity: 0.9; }
  70%  { r: 13; opacity: 0; }
  100% { r: 13; opacity: 0; }
}

.irr__readout {
  border-top: 1px solid var(--border);
  margin-top: 20px;
  padding-top: 20px;
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(120px, 1fr));
  gap: 18px;
}
.irr__rk { font-size: var(--t-micro); letter-spacing: 0.09em; text-transform: uppercase; color: var(--muted); margin-bottom: 6px; }
.irr__rv { font-size: 1.125rem; font-weight: 600; font-variant-numeric: tabular-nums; }
.irr__rv .u { font-size: 0.7em; color: var(--text-2); font-weight: 400; }

/* legend scale */
.irr__scale { display: flex; align-items: center; gap: 12px; margin-top: 22px; }
.irr__swatches { display: flex; flex: 1; height: 8px; border-radius: 2px; overflow: hidden; }
.irr__swatches i { flex: 1; display: block; }
.irr__scale-cap { font-size: var(--t-micro); color: var(--muted); white-space: nowrap; letter-spacing: 0.06em; }

@media (max-width: 900px) {
  .irr { grid-template-columns: minmax(0, 1fr); }
}

/* ==========================================================================
   Ambient — the page reads as an instrument, quietly
   ========================================================================== */

/* A single hairline that tracks read progress. No bar, no chrome. */
.progress {
  position: fixed; top: 0; left: 0; right: 0; z-index: 101;
  height: 1px; background: transparent; pointer-events: none;
}
.progress::after {
  content: '';
  display: block; height: 1px;
  width: var(--p, 0%);
  background: var(--olive-line);
  transition: width 0.1s linear;
}

/* Section index marks in the left margin on wide screens */
.section[data-mark] { position: relative; }
@media (min-width: 1500px) {
  .section[data-mark]::before {
    content: attr(data-mark);
    position: absolute;
    left: 22px;
    top: var(--section-y);
    font-size: 0.6875rem;
    letter-spacing: 0.14em;
    color: var(--olive-dim);
    writing-mode: vertical-rl;
    font-weight: 500;
  }
}

/* ==========================================================================
   06 · THE SWING — national frequency strip, site-wide footer
   A single hairline. It is the site's heartbeat, not its headline.
   ========================================================================== */
.swing {
  display: flex;
  align-items: center;
  gap: clamp(12px, 2vw, 28px);
  padding: 13px 0;
  border-top: 1px solid var(--border);
}
.swing__k {
  font-size: 0.6875rem; font-weight: 500; letter-spacing: 0.1em;
  text-transform: uppercase; color: var(--muted); white-space: nowrap;
}
.swing__canvas { flex: 1 1 auto; height: 38px; min-width: 0; display: block; }
.swing__v {
  font-size: 0.9375rem; font-weight: 600;
  font-variant-numeric: tabular-nums; letter-spacing: -0.01em;
  color: var(--text-2); white-space: nowrap;
  transition: color 0.4s var(--ease);
}
.swing.is-out .swing__v { color: var(--olive-ink); }
.swing__k--rocof { font-variant-numeric: tabular-nums; }
.swing__pips { display: inline-flex; gap: 5px; }
.swing__pips i {
  width: 4px; height: 4px; background: var(--border);
  transition: background 0.25s var(--ease);
}
.swing__pips i.is-latched { background: var(--warn); }

@media (max-width: 860px) {
  .swing__k--rocof, .swing__pips { display: none; }
}
@media (max-width: 600px) {
  .swing { flex-wrap: wrap; gap: 8px; }
  .swing__canvas { height: 28px; flex-basis: 100%; order: 3; }
}

/* ==========================================================================
   07 · THE ONE-LINE — DC load flow of the national transmission network
   Inline SVG, not canvas: hairlines must stay crisp at any DPR and every
   bus has to be focusable.
   ========================================================================== */
.sld {
  display: grid;
  grid-template-columns: minmax(0, 1.55fr) minmax(280px, 0.85fr);
  gap: clamp(20px, 3vw, 46px);
  align-items: start;
  margin-top: 34px;
}
.sld__stage {
  position: relative;
  border: 1px solid var(--border);
  border-radius: var(--r-card);
  background: #060706;
  padding: 10px;
  overflow: hidden;
}
.sld__svg { width: 100%; height: auto; display: block; }

.sld__prov { fill: none; stroke: #141712; stroke-width: 1; vector-effect: non-scaling-stroke; }

.sld__hit { stroke: transparent; stroke-width: 12; cursor: pointer; }
.sld__hit:focus-visible { stroke: rgba(155,179,117,0.25); outline: none; }
.sld__line { stroke: var(--olive-line); stroke-linecap: round; transition: stroke 0.3s var(--ease); }
.sld__flow {
  stroke: var(--olive-ink); stroke-dasharray: 1 9; stroke-linecap: round;
  opacity: 0.9; pointer-events: none;
}
.sld__br.is-open .sld__line { stroke: #2A2A2A; stroke-dasharray: 2 6; }
.sld__br.is-open .sld__flow { display: none; }
.sld__br.is-over .sld__line { stroke: var(--warn); }
.sld__br.is-over .sld__flow { stroke: var(--warn); }

.sld__glyph { fill: #060706; stroke: var(--olive-line); stroke-width: 1.4; }
.sld__tilde { fill: none; stroke: var(--olive-ink); stroke-width: 1.2; }
.sld__busbar { fill: rgba(255,255,255,0.55); }
.sld__draw { fill: none; stroke: var(--olive-line); stroke-width: 1.2; }
.sld__glyph--site { fill: var(--olive); stroke: var(--olive-ink); stroke-width: 1.6; }
.sld__ring { fill: none; stroke: var(--olive-dim); stroke-width: 1; stroke-dasharray: 2 4; }
.sld__bus--s.is-export .sld__glyph--site { fill: var(--olive-ink); }
.sld__bus--s.is-export .sld__ring { stroke: var(--olive-ink); }

.sld__lab {
  fill: var(--muted); font-size: 9px; font-weight: 500;
  letter-spacing: 0.06em; text-anchor: middle;
  font-family: 'Space Grotesk', Arial, sans-serif;
  paint-order: stroke; stroke: #060706; stroke-width: 2.5px;
}
.sld__lab--site { fill: var(--olive-ink); font-size: 10px; letter-spacing: 0.09em; }

.sld__panel { display: flex; flex-direction: column; gap: 20px; }
.sld__out { display: grid; grid-template-columns: 1fr 1fr; gap: 1px; background: var(--border); border: 1px solid var(--border); }
.sld__cell { background: var(--surface); padding: 13px 15px; display: flex; flex-direction: column; gap: 5px; min-width: 0; }
.sld__cell .u { font-size: 0.7em; color: var(--text-2); font-weight: 400; }
.sld__hint { font-size: var(--t-micro); color: var(--muted); line-height: 1.55; }

@media (max-width: 1000px) {
  .sld { grid-template-columns: minmax(0, 1fr); }
}
@media (prefers-reduced-motion: reduce) {
  .sld__flow { stroke-dasharray: none; opacity: 0.5; }
}

/* ==========================================================================
   08 · THE ALBEDO — bifacial rear-irradiance solve
   ========================================================================== */
.alb { display: grid; grid-template-columns: minmax(0, 1.6fr) minmax(260px, 0.8fr); gap: clamp(20px, 3vw, 46px); align-items: start; margin-top: 34px; }
.alb__stage { border: 1px solid var(--border); border-radius: var(--r-card); background: #060706; overflow: hidden; }
.alb__canvas { width: 100%; height: clamp(300px, 34vw, 430px); display: block; cursor: crosshair; touch-action: pan-y; }
.alb__panel { display: flex; flex-direction: column; gap: 20px; }
.alb__out { display: grid; grid-template-columns: 1fr 1fr; gap: 1px; background: var(--border); border: 1px solid var(--border); }
.alb__cell { background: var(--surface); padding: 13px 15px; display: flex; flex-direction: column; gap: 5px; min-width: 0; }
.alb__cell .u { font-size: 0.7em; color: var(--text-2); font-weight: 400; }
@media (max-width: 1000px) { .alb { grid-template-columns: minmax(0, 1fr); } }

/* ==========================================================================
   09 · THE TRANSFER — islanding + synchroscope
   10 · THE GALLOPING — torsional instability and stow
   Shared instrument shell: stage on the left, panel on the right.
   ========================================================================== */
.rig { display: grid; grid-template-columns: minmax(0, 1.6fr) minmax(250px, 0.78fr); gap: clamp(20px, 3vw, 46px); align-items: start; margin-top: 34px; }
.rig__stage { border: 1px solid var(--border); border-radius: var(--r-card); background: #060706; overflow: hidden; }
.rig__panel { display: flex; flex-direction: column; gap: 20px; }
.rig__out { display: grid; grid-template-columns: 1fr 1fr; gap: 1px; background: var(--border); border: 1px solid var(--border); }
.rig__cell { background: var(--surface); padding: 13px 15px; display: flex; flex-direction: column; gap: 5px; min-width: 0; }
.rig__cell .u { font-size: 0.7em; color: var(--text-2); font-weight: 400; }
.trf__canvas { width: 100%; height: clamp(280px, 30vw, 360px); display: block; }
.gal__canvas { width: 100%; height: clamp(300px, 32vw, 400px); display: block; }
.gal.is-divergent .rig__stage { border-color: var(--warn); }
@media (max-width: 1000px) { .rig { grid-template-columns: minmax(0, 1fr); } }

/* ==========================================================================
   11 · THE DRUM — 24-hour circular chart recorder
   12 · THE GNOMON — shadow conics and the row-pitch decision
   ========================================================================== */
.drum__svg, .gno__svg { width: 100%; height: auto; display: block; }
.drum__ring { fill: none; stroke: #16190F; stroke-width: 1; }
.drum__spoke { stroke: #14170F; stroke-width: 1; }
.drum__spoke--maj { stroke: var(--olive-dim); }
.drum__hr { fill: var(--muted); font-size: 9px; font-weight: 500; letter-spacing: 0.08em; text-anchor: middle; font-family: 'Space Grotesk', Arial, sans-serif; }
.drum__t { fill: none; stroke-linejoin: round; stroke-linecap: round; }
.drum__t--demand { stroke: var(--text-2); stroke-width: 1.2; }
.drum__t--pv { stroke: var(--olive-line); stroke-width: 1.2; stroke-dasharray: 3 3; }
.drum__t--net { stroke: var(--olive-ink); stroke-width: 2; }
.drum__exp { stroke: var(--olive); stroke-width: 1; opacity: 0.55; }
.drum__pen { stroke: var(--olive-ink); stroke-width: 1; opacity: 0.6; }
.drum__hub { fill: var(--border); }

.gno__c { fill: none; stroke-width: 1.2; }
.gno__c--win { stroke: var(--olive-ink); }
.gno__c--eq  { stroke: var(--olive-line); stroke-dasharray: 4 3; }
.gno__c--sum { stroke: var(--olive-dim); }
.gno__mark { fill: var(--olive-ink); }
.gno__rod { stroke: #fff; stroke-width: 2; }
.gno__shadow { stroke: var(--olive-line); stroke-width: 1.4; stroke-dasharray: 2 3; }
.gno__tip { fill: var(--olive-ink); }
.gno__row { stroke: var(--olive-ink); stroke-width: 2.4; stroke-linecap: round; }
.gno__dim { stroke: var(--olive-dim); stroke-width: 1; }
.gno__lab { fill: var(--muted); font-size: 9px; font-weight: 500; letter-spacing: 0.07em; text-anchor: middle; font-family: 'Space Grotesk', Arial, sans-serif; }
.gno__lab--dim { fill: var(--text-2); }

/* ==========================================================================
   13 · THE ETCH ANGLE   14 · THE DARK TEST   15 · THE AIR MASS
   ========================================================================== */
.etch__canvas { width: 100%; height: clamp(300px, 32vw, 400px); display: block; }
.dt__canvas   { width: 100%; height: clamp(260px, 27vw, 340px); display: block; cursor: crosshair; touch-action: pan-y; }
.am__canvas   { width: 100%; height: clamp(260px, 28vw, 340px); display: block; }
.rig__cell .is-reject, .hud__v.is-reject { color: var(--warn); }

/* ==========================================================================
   16 · THE PATHFINDER   17 · THE CURVE TRACER
   18 · THE SYNTHESIS    19 · THE TRANSIENT
   ========================================================================== */
.pf__canvas  { width:100%; height:clamp(320px,34vw,430px); display:block; cursor:crosshair; touch-action:none; }
.ct__canvas  { width:100%; height:clamp(300px,32vw,400px); display:block; }
.syn__canvas { width:100%; height:clamp(340px,36vw,460px); display:block; }
.tr__canvas  { width:100%; height:clamp(340px,36vw,460px); display:block; }
.rig--wide { grid-template-columns:minmax(0,1fr); }
.rig--wide .rig__panel { display:grid; grid-template-columns:repeat(auto-fit,minmax(220px,1fr)); gap:20px; align-items:start; }

/* ==========================================================================
   20–29 · the second series
   ========================================================================== */
.inc__canvas { width:100%; height:clamp(280px,28vw,360px); display:block; }
.tm__canvas  { width:100%; height:clamp(320px,34vw,430px); display:block; }
.sd__canvas  { width:100%; height:clamp(320px,34vw,430px); display:block; }
.kn__canvas  { width:100%; height:clamp(300px,32vw,400px); display:block; }
.pb__canvas  { width:100%; height:clamp(280px,28vw,360px); display:block; cursor:crosshair; touch-action:pan-y; }
.tp__canvas  { width:100%; height:clamp(280px,28vw,360px); display:block; }
.pn__canvas  { width:100%; height:clamp(300px,30vw,380px); display:block; }
.sc__canvas  { width:100%; height:clamp(300px,30vw,380px); display:block; }
.oc__canvas  { width:100%; height:clamp(220px,22vw,290px); display:block; }
.oc__svg     { width:100%; height:auto; display:block; }

.sl__svg { width:100%; height:auto; display:block; }
.sl__wire { stroke:var(--border); stroke-width:5; fill:none; stroke-linecap:round; }
.sl__flow { stroke:var(--olive-ink); stroke-dasharray:1 8; fill:none; stroke-linecap:round; }
.sl__edge.is-idle .sl__flow { display:none; }
.sl__edge.is-idle .sl__wire { stroke:#1A1A1A; }
.sl__box { fill:var(--surface); stroke:var(--border); stroke-width:1; }
.sl__name { fill:var(--text); font-size:11px; font-weight:500; text-anchor:middle; font-family:'Space Grotesk',Arial,sans-serif; }
.sl__nv, .sl__val { fill:var(--muted); font-size:9.5px; letter-spacing:0.06em; text-anchor:middle; font-family:'Space Grotesk',Arial,sans-serif; font-variant-numeric:tabular-nums; }
.sl__val { fill:var(--olive-ink); }
.sl__resid { fill:var(--muted); font-size:9px; text-anchor:end; font-family:'Space Grotesk',Arial,sans-serif; font-variant-numeric:tabular-nums; }
.is-shedding .sl__node--grid .sl__box { stroke:var(--warn); }

.oc__prov { fill:none; stroke:#141712; stroke-width:1; vector-effect:non-scaling-stroke; }
.oc__band { fill:none; stroke:rgba(155,179,117,0.18); stroke-width:34; stroke-linecap:round; }
.oc__centre { fill:none; stroke:var(--olive-ink); stroke-width:1.6; stroke-dasharray:6 4; }
.oc__dot { fill:var(--surface); stroke:var(--olive-line); stroke-width:1.4; }
.oc__site.is-on .oc__dot { fill:var(--olive-ink); stroke:var(--olive-ink); }
.oc__lab { fill:var(--muted); font-size:11px; font-family:'Space Grotesk',Arial,sans-serif; }
.oc__site.is-on .oc__lab { fill:var(--olive-ink); }
.oc__grid { display:grid; grid-template-columns:minmax(0,1fr) minmax(0,1fr); gap:14px; }
@media (max-width:760px){ .oc__grid { grid-template-columns:minmax(0,1fr); } }
