/* LED charge/outcome indicator — kept in its own file, deliberately, so
   a future animation-style experiment (post-launch, once there are real
   users to A/B) only ever touches this file + js/led.js, never main.css
   or game.js's press/hold logic. See js/led.js for the JS half; the two
   are a matched pair — an alternate style likely needs to change both.

   Press charge -- direct feedback (referencing an external FTU design
   doc's "Confirming" cell state) that there was previously no real sense
   of HOW MUCH LONGER to keep holding, just that something was pressed.
   Five LEDs light left to right over the real hold duration
   (LONGPRESS_MS, js/game.js, passed into js/led.js), matching the
   panel's own console-strip identity (see .colour-lights in main.css)
   rather than an abstract fill -- chosen over several other candidates
   (a bottom-up fill, a ring sweep, a radial iris, a whole-cell pulse)
   after a live side-by-side comparison (mocks/hold-charge-options.html,
   kept for reference). Discrete segments don't reduce to one continuous
   CSS property, so the charge-in-progress lighting is JS-timed
   (js/led.js's startCharge), not a pure transition like the candidates
   that lost out.

   Real DOM children, not a generated pseudo-element -- five
   independently-lit segments can't be one ::before/::after, there's
   only ever one of each.

   Fixed pixel sizing (6px inset, 5px height, 3px gap) at every board
   size, 4x4 through 9x9, deliberately NOT scaled down for smaller
   cells -- confirmed via the same mock (a real-size comparison section)
   that this stays legible even at a 9x9 board's ~34px cells; scaling
   the LEDs down proportionally there would make them sub-pixel thin. */
.leds {
  /* top, not bottom: the guided hold-demo's hand-cursor overflows the
     cell's bottom-right (see .hand-cursor in main.css) and visually
     covers a bottom-anchored strip during the one moment a player is
     being shown to watch it charge -- confirmed via a forced-state
     screenshot comparing both positions. Top clears it entirely and
     doesn't collide with .cell-verb (centered) either. */
  position: absolute; left: 6px; right: 6px; top: 6px; z-index: 2;
  display: flex; gap: 3px; pointer-events: none;
}
.led {
  flex: 1; height: 5px; border-radius: 2px; background: rgba(0,0,0,0.35);
  box-shadow: inset 0 1px 1px rgba(0,0,0,0.4);
  transition: background 400ms ease, box-shadow 400ms ease, opacity 400ms ease;
}
/* n>=5 boards (js/led.js's markup(subtle)) -- the same resting strip
   at 8x8 lines up edge-to-edge into a near-continuous seam across each
   row, confirmed distracting via direct screenshot. Dims the resting
   state way down while leaving the charging/outcome colours (which add
   .lit alongside them) completely untouched. */
.leds.subtle .led:not(.lit) { background: rgba(0,0,0,0.14); box-shadow: none; }
/* A resolved cell (marked/correct/wrong) already carries its own
   permanent icon (SVGS.mark/check/wrong) -- on a small cell the two
   compete for the same top strip, confirmed via a marked-up 8x8
   screenshot: the X's strokes crowd right up against the LED dashes.
   Once a cell has its icon, the LED has nothing left to say, so it
   fades out -- and back in if a mark is tapped off again (.marked is
   the only one of the three that ever reverses).
   :not(.lit) is load-bearing, not decorative: a MARKED cell can still
   be held again (the "Not that one" harness, js/game.js's freeFindMode
   block) and that hold must charge and flash red normally, so the hide
   has to stand down for as long as an active charge/outcome is using
   the LED -- same guard .subtle above uses for the same reason. */
.cell.marked .led:not(.lit),
.cell.correct .led:not(.lit),
.cell.wrong .led:not(.lit) {
  opacity: 0;
}
/* Charging (in progress) and cancelling (early release) both use the
   fast 120ms speed -- only the post-resolution outcome fade (below)
   uses the slow 400ms one, which is why .led's own base transition
   (used whenever .lit-correct/.lit-wrong is simply REMOVED, with
   nothing else applying) is the slow one, and .lit overrides it back
   to fast for the charging phase specifically. Also governs the fade
   IN when charging starts on an already-hidden marked cell -- faster
   than the 400ms fade-out so the charge itself still feels snappy. */
.led.lit { background: #fff; box-shadow: 0 0 6px 1px rgba(255,255,255,0.8); opacity: 1; transition: background 120ms ease, box-shadow 120ms ease, opacity 120ms ease; }
/* Outcome colour once the hold completes -- #6abf7a and #e03030 are the
   real game's own success/wrong colours (SVGS.check/SVGS.wrong in
   js/engine.js), not new ones invented for this. Direct feedback,
   confirmed via the same mock (an outcome-colour section, and a real-
   board section with two cells pre-solved): the colour should NOT stay
   lit permanently once a cell is solved -- the checkmark (svg-check,
   already permanent) and the cell's own pressed-in .correct styling
   already carry that long-term signal; a LED strip staying green on
   every solved cell for the rest of the level just adds competing
   colour on top of the region hues a player still needs to read for
   the cells that aren't solved yet. See js/led.js's resolve() for the
   timing that removes these two classes again after the outcome beat.*/
.led.lit-correct { background: #6abf7a; box-shadow: 0 0 8px 2px rgba(106,191,122,0.85); opacity: 1; transition: background 120ms ease, box-shadow 120ms ease, opacity 120ms ease; }
.led.lit-wrong   { background: #e03030; box-shadow: 0 0 8px 2px rgba(224,48,48,0.85); opacity: 1; transition: background 120ms ease, box-shadow 120ms ease, opacity 120ms ease; }
