/* Lithiation lattice widget - extracted from the approved concept C mockup. */
.widget{
  position:relative; height:480px; display:flex; flex-direction:column;
  background:var(--panel); border:1px solid var(--hair); border-radius:14px;
  overflow:hidden; box-shadow:0 24px 70px rgba(0,0,0,.45);
  user-select:none; -webkit-user-select:none;
  container-type:inline-size;
}
/* (original vh-based height removed - see the fixed breakpoints below) */
.whead{display:flex; justify-content:space-between; align-items:center;
  gap:10px; padding:13px 16px 12px; border-bottom:1px solid var(--hair)}
.whead .cap{color:var(--mut)}
.chip{font-family:var(--disp); font-weight:500; font-size:9px;
  letter-spacing:.16em; text-transform:uppercase; color:var(--mut);
  border:1px solid var(--hair2); border-radius:999px; padding:5px 10px;
  white-space:nowrap; transition:color .3s, border-color .3s}
.chip.hot{color:var(--voltB); border-color:rgba(47,214,163,.45)}
.stage{position:relative; flex:1; min-height:225px; cursor:grab;
  touch-action:pan-y; outline:none}
/* The phase chip must never wrap or reflow the title beside it - that changed
   the header height by 26px and resized the canvas with it. */
.whead .chip{white-space:nowrap; flex:none}
.whead .cap{min-width:0}
/* Narrow + tall proportions: the lattice reads better as a deep column,
   giving the reaction front a longer distance to sweep.

   Heights are fixed per breakpoint and deliberately NOT viewport units.
   calc(100vh - Npx) varies continuously, so any sub-pixel change in viewport
   height resizes the canvas, and every resize triggers a full buildLattice()
   - which is what makes the panel visibly expand/contract and hitch during
   scrolling. It is worst when the calc result lands on the clamp boundary,
   and on mobile where 100vh changes as browser chrome hides. Discrete
   breakpoints only re-evaluate on a real resize. */
.widget{height:620px}
@media (max-height:880px){ .widget{height:560px} }
@media (max-height:780px){ .widget{height:490px} }
@media (max-height:680px){ .widget{height:430px} }
@media (max-width:1199px){ .widget{height:520px} }
@media (max-width:1199px) and (max-height:780px){ .widget{height:440px} }
.stage:active{cursor:grabbing}
.stage:focus-visible{box-shadow:inset 0 0 0 1px rgba(47,214,163,.55)}
.stage canvas{position:absolute; inset:0; width:100%; height:100%; display:block}
.reads{display:grid; grid-template-columns:1fr 1.28fr 1fr;
  border-top:1px solid var(--hair)}
.tile{padding:11px 14px 9px; border-left:1px solid var(--hair); min-width:0}
.tile:first-child{border-left:none}
.tl{font-family:var(--disp); font-weight:500; font-size:8.5px;
  letter-spacing:.2em; text-transform:uppercase; color:var(--dim);
  white-space:nowrap; overflow:hidden}
.tv{font-family:var(--disp); font-weight:600; font-size:21px; line-height:1.2;
  color:var(--ink); font-feature-settings:'tnum' 1; white-space:nowrap;
  margin-top:3px}
.tv .tu{font-size:10.5px; color:var(--mut); font-weight:500;
  letter-spacing:.02em; margin-left:2px}
@container (max-width:368px){
  .tv{font-size:17px}
  .tile{padding:10px 10px 8px}
  .wfootR{display:none}
}
.capbar{position:relative; height:32px; margin:2px 16px 0; cursor:pointer;
  touch-action:pan-y}
.cbLabL,.cbLabR{position:absolute; top:1px; font-family:var(--disp);
  font-weight:500; font-size:8px; letter-spacing:.14em; text-transform:uppercase;
  color:var(--dim); white-space:nowrap}
.cbLabR{right:0}
.cbTrack{position:absolute; left:0; right:0; top:19px; height:3px;
  background:rgba(233,238,247,.09); border-radius:2px}
.cbFill{position:absolute; left:0; top:19px; height:3px; width:0%;
  background:linear-gradient(90deg,var(--voltD),var(--volt));
  border-radius:2px}
.cbTick{position:absolute; left:10.39%; top:14px; width:1px; height:13px;
  background:rgba(233,238,247,.30)}
.cbKnob{position:absolute; left:0%; top:20.5px; width:9px; height:9px;
  border-radius:50%; background:var(--voltB);
  transform:translate(-50%,-50%);
  box-shadow:0 0 9px rgba(47,214,163,.75)}
/* Fixed height, not min-height. The narration strings wrap to 1-3 lines, and
   .stage is flex:1, so any change here resizes the canvas and forces a full
   buildLattice() - mid-scroll, at every phase transition. Sized to the
   tallest string; shorter ones just leave space. */
.narr{padding:8px 16px 0; font-size:11px; line-height:1.5; color:var(--mut);
  height:46px; overflow:hidden; transition:opacity .22s}
.narr.swap{opacity:0}
.wfoot{margin-top:6px; padding:8px 16px 11px; border-top:1px solid var(--hair);
  display:flex; justify-content:space-between; align-items:baseline; gap:10px}
.wfoot .cap{font-size:9px; letter-spacing:.2em}
.wfootR{font-size:8.5px; color:var(--dim); font-family:var(--disp);
  letter-spacing:.18em; text-transform:uppercase; white-space:nowrap}
