/* ═══════════════════════════════════════════════════════════════════
   GN COLLECTION — THE CONSOLE AND THE COST LANDSCAPE (styles)
   Lifted out of p1.html on 1 Sep 2026 so two pages can wear it:
     /p1          the project page, where it sits inside the argument
     /ghostnets   the instrument on its own, a link she can hand out
   The markup lives in both pages; this file and gnlab.js are the one
   copy of everything that isn't markup. Change a colour here and both
   pages change together — that is the whole point of the split.
   Load it AFTER editorial.css: several rules here win on order alone.
   ═══════════════════════════════════════════════════════════════════ */

/* ═══ THE BOARD ═══ */
/* --b-panel is deliberately near-black in BOTH themes — it is the token
   for the dark pixel screens, not a surface colour. Using it for the
   board's chrome put light-mode text, which flips dark, onto a black
   panel at 1.07:1. The chrome follows the page; only the canvas stays a
   screen. */
/* The note above the console. Every colour here carries !important on
   purpose: editorial.css flattens colour on h1-h6/p/li/span with
   `color:inherit !important` to keep the skin uniform, and the file's own
   comment says the way back is a more specific !important rule. */
.lab-intro{ width:min(1180px,calc(100vw - 2.4rem)); margin:2.6rem auto .9rem; }
.lab-intro h2{ font-size:.62rem; letter-spacing:.16em; text-transform:uppercase;
      color:var(--b-muted) !important; margin:0 0 .6rem; font-weight:700; }
.lab-intro p{ margin:0 0 .5rem; max-width:62ch; font-size:.86rem; line-height:1.75;
      color:var(--b-ink) !important; }
.lab-intro p:last-of-type{ margin-bottom:0; }
.lab-intro p b{ font-weight:700; color:var(--b-ink) !important; }
/* measured in rem, not ch: at this font-size 62ch collapsed the two
   columns to 172px and broke every line. */
.lab-key{ list-style:none; margin:1rem 0 0; padding:0;
      display:grid; gap:.32rem 1.4rem; max-width:46rem;
      font-size:.62rem; letter-spacing:.03em; line-height:1.65;
      color:var(--b-muted) !important; }
@media(min-width:700px){ .lab-key{ grid-template-columns:1fr 1fr; } }
.lab-key li{ padding-left:.9rem; position:relative; color:var(--b-muted) !important; }
.lab-key li::before{ content:''; position:absolute; left:0; top:.5em;
      width:5px; height:5px; background:var(--b-acc); }
/* and the one line under the whole instrument. The console's own bottom
   margin is pulled in when this follows it, rather than cancelled with a
   negative margin that would drift if either value changed. */
.lab:has(+ .lab-foot){ margin-bottom:1rem; }
.lab-foot{ width:min(1180px,calc(100vw - 2.4rem)); margin:0 auto 3rem;
      font-size:.72rem; line-height:1.7; color:var(--b-muted) !important; }
.lab-foot span{ display:block; max-width:70ch; color:var(--b-muted) !important; }

.lab{ width:min(1180px,calc(100vw - 2.4rem)); margin:2.2rem auto 3rem;
      border:2px solid var(--b-ink); background:var(--b-bg);
      font-family:var(--b-mono,ui-monospace,Menlo,monospace); }
.lab-strip{ display:flex; flex-wrap:wrap; align-items:center; gap:.7rem;
      padding:.5rem .8rem; border-bottom:2px solid var(--b-ink);
      font-size:0.66rem; letter-spacing:.1em; text-transform:uppercase;
      color:var(--b-muted); font-variant-numeric:tabular-nums; }
.lab-strip b{ color:var(--b-ink); font-weight:700; }
.lab-warn{ margin-left:auto; color:var(--b-b2); font-weight:700; }
.lab-body{ display:grid; grid-template-columns:1fr; }
@media(min-width:900px){ .lab-body{ grid-template-columns:170px 1fr 250px; } }
.lab-left,.lab-right{ padding:.8rem; }
@media(min-width:900px){
  .lab-left{ border-right:2px solid var(--b-ink); }
  .lab-right{ border-left:2px solid var(--b-ink); }
}
.lab-mid{ padding:.8rem; min-width:0; }
.ctrl-row{ display:block; font-size:0.66rem; letter-spacing:.08em;
      text-transform:uppercase; color:var(--b-muted); margin-bottom:.85rem; }
.ctrl-row .val{ float:right; color:var(--b-ink); font-variant-numeric:tabular-nums; }
.ctrl-row input[type=range]{ width:100%; margin-top:.3rem; }
.lab-rule{ border:0; border-top:1px solid var(--b-line2); margin:.9rem 0; }
.lab-acct{ font-size:0.66rem; line-height:1.9; color:var(--b-faint);
      letter-spacing:.06em; text-transform:uppercase; }
/* the chart keeps the field's true 600:380 aspect, whatever the column
   width — a fixed height stretched storms into ellipses next to their
   own perfectly round dashed outlines */
.board-wrap{ position:relative; aspect-ratio:600/380; max-height:640px;
  border:1px solid var(--b-line2); }

/* the console chart is SHARP by request — the pixel art belongs to the
   figures below, this panel is the tool */
#p1-board{ width:100%; height:100%; display:block; image-rendering:auto; }
/* the figure is light in both themes: it is a plot, and a resistance
   scale that followed the hue slider would be a scale that lies */
.board-wrap{ background:#f4f8fd !important; border-color:#c9d4de !important; }
.board-legend{ position:absolute; right:.5rem; top:.4rem;
  font-size:0.66rem; letter-spacing:.05em; display:flex; gap:.75rem;
  align-items:center; background:rgba(244,248,253,.92);
  border:1px solid #c9d4de; padding:.2rem .45rem; color:#1a1a1a;
  pointer-events:none; }
.board-legend .lg-div{ display:flex; align-items:center; gap:.3rem; }
.board-legend .lg-div i{ display:block; width:46px; height:7px;
  background:linear-gradient(90deg,#b2182b,#f7f7f7,#2166ac); }
.board-legend .lg-gr{ color:#4a545e; } .board-legend .lg-rp{ color:#2e4057; }
.board-legend .lg-net{ display:flex; align-items:center; gap:.28rem; }
.board-legend .lg-net b{ width:7px; height:7px; border-radius:50%;
  background:#2e7d4f; display:block; }
/* closed water: the hatched core of a storm where the sea is over the
   vessel's limit — the same hatch the chart draws */
.board-legend .lg-nogo{ display:flex; align-items:center; gap:.28rem; }
.board-legend .lg-nogo i{ display:block; width:12px; height:9px; box-sizing:border-box;
  border:1px solid #b2182b;
  background:repeating-linear-gradient(135deg, transparent 0 2px, rgba(178,24,43,.55) 2px 3px); }
.board-scale{ position:absolute; left:.5rem; bottom:.4rem;
  display:flex; align-items:center; gap:.35rem; font-size:0.66rem;
  color:#1a1a1a; background:rgba(244,248,253,.92); border:1px solid #c9d4de;
  padding:.15rem .4rem; pointer-events:none; }
.board-time{ display:flex; align-items:center; gap:.7rem; margin:.55rem 0 0; }
.board-time .tplay{ width:2.4rem; flex:none; }
.board-time input[type=range]{ flex:1; min-width:0; accent-color:var(--b-acc); }
#t-clock{ font:600 11px/1 var(--b-mono, ui-monospace, monospace);
  color:var(--b-muted); flex:none; min-width:4.4rem; text-align:right; }
.board-scale i{ display:block; width:74px; height:7px;
  background:linear-gradient(90deg,#f7fbff,#c6dbef,#6baed6,#2171b5,#08306b); }
.lab-tog{ display:flex; align-items:center; gap:.45rem; font-size:0.66rem;
  letter-spacing:.06em; text-transform:uppercase; color:var(--b-muted);
  margin:.3rem 0; cursor:pointer; }
.lab-tog input{ accent-color:var(--b-acc); }
.lab-tog .ls{ display:inline-block; width:16px; flex:none; border-top:2px solid var(--b-acc); }
.lab-tog .ls.dash{ border-top-style:dashed; border-top-color:var(--b-b2); }
.lab-tog .ls.dot{ border-top-style:dotted; border-top-color:var(--b-faint); }
.lab-tog .ls.storm{ border-top-style:dashed; border-top-color:var(--b-b2); width:10px; }
.lab-tog .ls.chase{ border-top-color:#b2182b; border-top-width:3px; width:12px; }
#t-status{ color:var(--b-acc); font-weight:700; }
/* the convergence subfigure: paper in both themes, like the chart */
.curve-cv{ width:100%; height:96px; display:block;
  background:#f4f8fd; border:1px solid #c9d4de; }

/* p1 only: plain white paper, no hue system. The one accent is the
   card's steel blue; the theme toggle is hidden because white is the
   design here, not a preference. */
html[data-theme="light"]{
  --b-acc:#1d4e73;
  --b-b1:#245c8a; --b-b1-ink:#ffffff;
  --b-b2:#5a646e; --b-b2-ink:#ffffff;
}
.theme-toggle{ display:none !important; }
#t-status{ color:#1d4e73; }
.btn.inst.active{ background:var(--b-ink); color:var(--b-bg); }
.stoplist{ max-height:230px; overflow:auto; }
.board-legend .lg-you{ color:var(--b-ink); }
.board-legend .lg-opt{ color:var(--b-acc); }
.board-legend .lg-gr{ color:var(--b-b2); }
.board-legend .lg-rp{ color:var(--b-faint); }
.arc-line{ min-height:2.6rem; margin-top:.5rem; padding:.4rem .5rem;
      border:1px solid var(--b-line2); font-size:0.66rem; line-height:1.7;
      color:var(--b-muted); display:flex; flex-wrap:wrap; gap:.1rem .9rem;
      font-variant-numeric:tabular-nums; }
.arc-line b{ color:var(--b-ink); }
.arc-line .good{ color:var(--b-acc); font-weight:700; }
.arc-line .bad{ color:var(--b-b2); font-weight:700; }
.rail-h{ font-size:0.66rem; letter-spacing:.14em; text-transform:uppercase;
      color:var(--b-muted); margin:0 0 .5rem; font-weight:700; }
.stoplist{ list-style:none; margin:0; padding:0; }
.stop{ display:flex; align-items:center; gap:.35rem; padding:.22rem 0;
      font-size:0.66rem; border-bottom:1px solid var(--b-line2);
      font-variant-numeric:tabular-nums; }
.stop .ord{ color:var(--b-faint); }
.stop .nm{ color:var(--b-ink); font-weight:700; }
.stop .kg{ color:var(--b-muted); }
.stop .dlt{ margin-left:auto; font-weight:700; }
.stop .dlt.neg{ color:var(--b-acc); } .stop .dlt.pos{ color:var(--b-muted); }
.stop.over{ opacity:.5; text-decoration:line-through; }
.stop.over .dlt{ color:var(--b-b2); text-decoration:none; }
.stop.closed .dlt{ color:#b2182b; }
.stop .acts button{ background:none; border:0; color:var(--b-faint);
      cursor:pointer; font-size:.6rem; padding:0 .12rem; }
.stop .acts button:hover{ color:var(--b-ink); }
.rail-empty{ font-size:0.66rem; color:var(--b-faint); line-height:1.6; }
.rail-add{ display:flex; gap:.3rem; margin-top:.6rem; }
.rail-add select{ flex:1; min-width:0; font-family:inherit; font-size:0.66rem;
      background:var(--b-bg); color:var(--b-ink);
      border:1px solid var(--b-line2); padding:.25rem; }
.ratio-eq{ font-size:0.66rem; color:var(--b-faint); }
.ratio-big{ font-size:1.5rem; font-weight:700; color:var(--b-ink);
      line-height:1.2; font-variant-numeric:tabular-nums; }
.ratio-big small{ font-size:0.66rem; font-weight:400; color:var(--b-muted); }
.ratio-sub{ font-size:0.66rem; color:var(--b-muted); letter-spacing:.06em; }
#b-fsolve.stale{ opacity:.4; }
.lam-note{ font-size:0.66rem; color:var(--b-faint); line-height:1.55; margin:.4rem 0 0; }
.lab-res{ border-top:2px solid var(--b-ink); padding:.8rem; }
.resrow{ display:flex; align-items:center; gap:.6rem; margin-bottom:.4rem;
      font-size:0.66rem; font-variant-numeric:tabular-nums; }
/* the band, her prototype's reading: names uppercase, the winner's own
   name in accent and bold behind an uppercase MIN marker. editorial.css
   already hatches the losers and solidifies the winner's bar. */
.resrow .rl{ width:9.5rem; flex:none; color:var(--b-muted);
      text-transform:uppercase; letter-spacing:.08em;
      letter-spacing:.1em; text-transform:uppercase; }
.resrow .rbar{ flex:1; min-width:40px; height:13px; background:var(--b-line2); }
.resrow .rbar i{ display:block; height:100%; background:var(--b-b2); }
.resrow.best .rbar i{ background:var(--b-acc); }
.resrow.best .rl{ color:var(--b-acc) !important; font-weight:700; }
.resrow.best .rl::before{ content:'MIN \25B8  '; }
.resrow.best .rv{ color:var(--b-acc) !important; font-weight:700; }
.resrow .rv{ width:6.5rem; flex:none; text-align:right; color:var(--b-ink); }
.resrow .rn{ width:8rem; flex:none; text-align:right; color:var(--b-faint); }
.lab-bar{ display:flex; flex-wrap:wrap; gap:.4rem; padding:.7rem .8rem;
      border-top:2px solid var(--b-ink); }
.lab-bar .btn{ font-family:inherit; font-size:0.66rem; letter-spacing:.1em;
      text-transform:uppercase; padding:.42rem .8rem; cursor:pointer;
      background:var(--b-bg); color:var(--b-ink);
      border:2px solid var(--b-ink); }
.lab-bar .btn:hover{ background:var(--b-ink); color:var(--b-bg); }
.lab-bar .btn-fill{ background:var(--b-b1); color:var(--b-b1-ink);
      border-color:var(--b-b1); margin-left:auto; }
/* ═══ PHONES ═══
   This block sits at the END of the sheet on purpose. Placed earlier it
   lost to the base .lab rules below it — same specificity, later wins,
   media query or not — which is why the select stayed at 9px.
   Measured on a 375px screen before this block: the smallest text in the
   console was 8px, the controls 9.3px, the stop-list buttons 10x12px and
   the checkboxes 13px — against a 44px touch-target guideline. The legend
   and the scale, corner chips on a desktop, covered a fifth of a chart
   that was itself only 19% of the screen height. */
@media(max-width:899px){
  /* the chart keeps its aspect; the legend and scale stop sitting on top
     of it and become rows underneath, inside the same frame */
  .board-wrap{ aspect-ratio:auto; max-height:none; }
  #p1-board{ height:auto; aspect-ratio:600/380; }
  .board-legend,.board-scale{ position:static; border:0; border-top:1px solid #c9d4de;
    width:auto; padding:.4rem .5rem; background:none; font-size:0.66rem;
    display:flex; flex-wrap:wrap; align-items:center; gap:.5rem; }
  .board-legend{ justify-content:flex-start; }

  /* type: nothing in the console below 11px */
  .lab-strip,.lab-tog,.ctrl-row,.rail-h,.arc-line,.lab-acct,.stop,.ratio-sub,
  .lam-note,.storm-note,.rail-empty,.resrow,.ratio-eq,.lab-bar .btn,
  .board-legend,.board-legend span,.board-scale,.board-scale span{
    font-size:.72rem !important; }
  .lab-strip{ gap:.45rem .8rem; }
  .lab-key{ font-size:.72rem; }

  /* the result rows carry three fixed columns adding up to 25rem plus
     the bar, which needs about 450px. A phone has 375, body clips the
     overflow, and the last column — the one with the kilograms in it —
     was simply gone. The label takes its own line instead. */
  .resrow{ flex-wrap:wrap; }
  .resrow .rl{ width:100%; }
  .resrow .rv{ width:auto; min-width:5rem; }
  .resrow .rn{ width:auto; }

  /* touch targets. 16px on the select because iOS zooms the whole page
     when a focused control is smaller than that. */
  .lab-tog{ min-height:44px; gap:.7rem; margin:0; }
  .lab-tog input[type=checkbox]{ width:22px; height:22px; flex:none; }
  .ctrl-row{ padding:.35rem 0; }
  .lab input[type=range]{ height:34px; }
  .rail-add select{ font-size:16px; min-height:44px; }
  .ratio-big small{ font-size:.72rem; }
  .rail-add .btn,.lab-bar .btn{ min-height:44px; padding:.6rem 1rem; }
  .board-time .tplay{ min-width:44px; min-height:44px; font-size:1rem; }
  .board-time input[type=range]{ height:34px; }
  #b-stops .acts button{ width:34px; height:34px; font-size:.8rem; }
  .stop{ gap:.35rem; padding:.3rem 0; }
  .stoplist{ max-height:none; }

  /* the buttons under the console stack into reachable rows */
  .lab-bar{ gap:.5rem; }
  .lab-bar .btn{ flex:1 1 45%; }
  .lab-bar .btn-fill{ flex-basis:100%; margin-left:0; }
}

/* ═══ THE COST LANDSCAPE ═══
   The resistance field the chart above draws flat, drawn instead as
   terrain: height is litres per hour. Ridgelines rather than a filled
   mesh, which is how her own surface plots read and costs nothing to
   draw. */
.cost-wrap{ width:min(1180px,calc(100vw - 2.4rem)); margin:0 auto 3rem; }
.cost-h{ font-size:.72rem; letter-spacing:.16em; text-transform:uppercase;
  color:var(--b-muted) !important; margin:0 0 .6rem; font-weight:700; }
.cost-lead{ margin:0 0 .9rem; max-width:62ch; font-size:.86rem; line-height:1.75;
  color:var(--b-ink) !important; }
.cost-box{ position:relative; border:1px solid #c9d4de; background:#ffffff; }
.cost-box svg{ display:block; width:100%; height:auto; touch-action:none; }

.cost-read{ display:flex; flex-wrap:wrap; align-items:baseline; gap:.4rem 1.8rem;
  margin-top:.8rem; font-family:var(--b-mono,ui-monospace,Menlo,monospace);
  font-size:.72rem; letter-spacing:.04em; color:var(--b-muted) !important;
  font-variant-numeric:tabular-nums; }
.cost-read b{ color:var(--b-ink) !important; font-weight:700; }
.cost-read .hot{ color:#b2182b !important; font-weight:700; }
/* the two numbers the picture exists to deliver, at the size of an answer */
.cost-read .big{ font-size:1.6rem; font-weight:700; letter-spacing:-.01em;
  color:var(--b-ink) !important; line-height:1; }
.cost-read .big small{ font-size:.72rem; font-weight:400; letter-spacing:.06em;
  color:var(--b-muted) !important; margin-left:.25rem; }
.cost-read .cols{ display:flex; flex-wrap:wrap; gap:.3rem 1.2rem; }
.cost-time{ display:flex; align-items:center; gap:.8rem; margin-top:.9rem;
  font-family:var(--b-mono,ui-monospace,Menlo,monospace); font-size:.7rem;
  letter-spacing:.08em; text-transform:uppercase; color:var(--b-muted) !important; }
.cost-time input[type=range]{ flex:1; min-width:0; max-width:26rem;
  accent-color:var(--b-acc); height:30px; }
#cost-meet-v{ min-width:5.5rem; text-align:right; font-weight:700;
  color:var(--b-ink) !important; font-variant-numeric:tabular-nums; }
@media(max-width:899px){ .cost-time input[type=range]{ height:44px; } }
.cost-actions{ display:flex; align-items:center; gap:.9rem; flex-wrap:wrap; margin-top:.9rem; }
.cost-actions .btn{ font-family:var(--b-mono,ui-monospace,Menlo,monospace);
  font-size:.66rem; letter-spacing:.1em; text-transform:uppercase;
  padding:.5rem .9rem; cursor:pointer;
  background:var(--b-bg); color:var(--b-ink) !important;
  border:2px solid var(--b-ink); }
.cost-actions .btn:hover{ background:var(--b-ink); color:var(--b-bg) !important; }
.cost-actions .btn[disabled]{ opacity:.5; cursor:default; }
.cost-note{ font-family:var(--b-mono,ui-monospace,Menlo,monospace);
  font-size:.66rem; color:var(--b-muted) !important; }
@media(max-width:899px){ .cost-actions .btn{ min-height:44px; } }
@media(max-width:899px){
  .cost-box{ aspect-ratio:1180/560; }
  .cost-read{ font-size:.72rem; gap:.3rem 1rem; }
}

/* ═══ PLAIN ═══════════════════════════════════════════════════════════
   The console as /ghostnets wears it: one frame instead of eleven. On
   /p1 the instrument sits inside a long argument and the rules help the
   eye find its edges; standing on its own page it only has to be itself,
   and the boxes started reading as apparatus.

   Every rule below removes a border or quiets a line. Not one of them
   changes a control, a reading or a number — the page passes the same
   class to the same markup, and gnlab.js never looks at it. Add `plain`
   to the body of /p1 and it gets the same treatment.
   ═══════════════════════════════════════════════════════════════════ */
.plain .lab{ border-width:1px; border-color:var(--b-line2); }
.plain .lab-strip{ border-bottom:1px solid var(--b-line2); }
@media(min-width:900px){
  /* air between the rails and the chart instead of a rule, which needs
     a little more of it than a border did */
  .plain .lab-body{ grid-template-columns:178px 1fr 254px; }
  .plain .lab-left{ border-right:0; padding-right:1.2rem; }
  .plain .lab-right{ border-left:0; padding-left:1.2rem; }
}
.plain .board-wrap{ border:0; }
/* the legend and the scale lose their frames and go back to being
   labels. The pale wash under them stays: they sit ON the chart, and a
   storm can put deep blue exactly where the legend is — dropping it
   entirely traded a border for an unreadable line. */
.plain .board-legend,.plain .board-scale{ border:0;
  background:rgba(244,248,253,.84); }
.plain .arc-line{ border:0; padding:.45rem 0 0; }
.plain .curve-cv{ border:0; }
.plain .lab-res,.plain .lab-bar{ border-top:1px solid var(--b-line2); }
.plain .stop{ border-bottom:0; padding:.26rem 0; }
.plain .rail-add select{ border:1px solid var(--b-line2); }
/* the row of buttons was seven black rectangles; a hairline is enough to
   say "pressable", and editorial.css's 2px !important has to be told */
.plain .lab-bar .btn{ border:1px solid var(--b-line2) !important; }
.plain .lab-bar .btn:hover{ border-color:var(--b-ink) !important; }
/* and the loaded example finally shows which one it is: editorial.css
   flattens .btn with !important, so the active state never landed */
.plain .lab-bar .btn.inst.active{ background:var(--b-ink) !important;
  color:var(--b-bg) !important; border-color:var(--b-ink) !important; }
/* .storm-note has no base rule anywhere, so this line — the only prose
   in the left rail — came out at browser default size next to 10px type */
.plain .storm-note{ font-size:0.66rem; line-height:1.6; margin:.35rem 0 0;
  color:var(--b-faint) !important; }
/* the strip on /ghostnets carries only the badge, and .lab-warn pushes
   itself right with margin-left:auto — alone, that stranded it across an
   empty bar. First child means it is the only thing there. */
.plain .lab-warn:first-child{ margin-left:0; }

/* ═══ PLAIN, ON A PHONE ═══════════════════════════════════════════════
   The desktop console is three columns: controls, chart, route. Stacked
   on a phone in that order the chart — the thing itself — arrived after
   six hundred pixels of sliders. So on a narrow screen the order is what
   a thumb wants: the chart first, then the route it builds, then the
   things you can change; the controls pack two and three to a row, and
   the convergence plot — a diagnostic — stays on the wide screen. Scoped
   to .plain: /p1 keeps its own phone layout. */
@media(max-width:899px){
  .plain .lab-body{ display:flex; flex-direction:column; }
  .plain .lab-mid{ order:1; padding:.6rem .6rem 0; }
  .plain .lab-right{ order:2; padding:.8rem .8rem .2rem; }
  .plain .lab-left{ order:3; padding:.4rem .8rem .8rem; }

  /* the controls pack: sliders full width but tighter, the two
     algorithm toggles side by side, the three storms in one row */
  .plain .lab-left{ display:flex; flex-wrap:wrap; align-items:center; gap:0 .7rem; }
  .plain .lab-left > *{ flex:1 1 100%; }
  .plain .lab-left .ctrl-row{ padding:.1rem 0; margin-bottom:.35rem; }
  .plain .lab-left .lab-rule{ margin:.5rem 0; }
  .plain .lab-left .rail-h{ margin:.1rem 0 .2rem; }
  .plain .lab-left .lab-tog{ min-height:40px; margin:0; }
  /* the three storms share a row; their labels are short enough not to
     wrap once the gaps inside the row are trimmed */
  .plain .lab-left .lab-tog:has(input[id^="storm-"]){ flex:1 1 26%; gap:.3rem; }
  .plain .lab-left .lab-tog:has(input[id^="storm-"]) span{ white-space:nowrap; }
  .plain .lab-left .lab-tog:has(input[id^="storm-"]) .ls{ width:8px; }
  .plain .lab-left .storm-note{ margin:0 0 .2rem; }

  /* the route rail: the list, the ratio, nothing else */
  .plain .lab-right .rail-h:has(+ .curve-cv),
  .plain .lab-right .lab-rule:has(+ .rail-h + .curve-cv),
  .plain .lab-right .curve-cv{ display:none; }

  /* the three examples share one row; the rest pair up */
  .plain .lab-bar{ gap:.4rem; }
  .plain .lab-bar .btn.inst{ flex:1 1 28%; }
  .plain .lab-bar .btn{ padding:.55rem .4rem; }
  .plain .lab-res{ padding:.6rem .8rem .3rem; }
}
