/* ==========================================================================
   NetrAI — Client marquee as a Pixel LED board

   The client names used to be a row of <span>s translated by a CSS keyframe.
   They are now drawn as a dot-matrix board by the OriginKit component
   `pixel-led-display` (js/effects/pixel-led-display.js), which does its own scrolling.

   THE NAMES ARE STILL IN THE MARKUP. A canvas of dots is a picture of words,
   not words — so the original spans stay in the DOM, visually hidden, and the
   board renders from their text. One place to edit, and the section still reads
   as a list of clients to a screen reader and to a crawler.

   The section keeps its own surface, hairlines and edge mask from
   style.css / refine.css; this file only carves out the board.
   ========================================================================== */

:root {
  /* lit dots — the brand blue, matching the hero field */
  --led-on: #0071e3;
  /* unlit dots. Without these the board reads as floating text rather than as
     a panel with most of its lamps off, which is the whole look. Kept very
     faint: at 0.07 on white it is a texture, at 0.15 it is a grid. */
  --led-off: rgba(0, 0, 0, 0.07);
  /* no bloom on white — over blue it muddies the dots rather than lighting them */
  --led-glow: 0;

  /* --- board size -------------------------------------------------------
     These three move together and js/effects/led-marquee.js reads all three, so the
     size of the board lives here rather than half here and half in JS.

       --led-board-h    the host's height. The canvas is `height: 100%` of it.
       --led-text-size  the component's `textSize`: the glyph block's height in
                        CSS px. Cell size is this / 7 rows, so it is what
                        actually sets the pitch of the grid.
       --led-dot-size   the component's `dotSize`, a diameter. Must stay under
                        the cell (textSize / 7) or the dots touch and the board
                        turns into a solid bar.

     UNITLESS on purpose for the latter two — they are passed to the component
     as numbers, not as CSS lengths. */
  --led-board-h: 26px;
  --led-text-size: 20;
  --led-dot-size: 2.2;
}

[data-theme="dark"] {
  --led-on: #2997ff;
  --led-off: rgba(255, 255, 255, 0.09);
  /* on black the bloom is what sells it as an emitter rather than a print */
  --led-glow: 1;
}

/* --------------------------------------------------------------------------
   The board
   -------------------------------------------------------------------------- */

/* The board replaced a ~17px row of type, so the section's original 40px of
   padding would open a hole between the hero and the first chapter. 12px either
   side of a 26px board puts the band at 50px — a quiet footnote between two
   big sections, sized closer to the text row it replaced than to a section of
   its own. Scoped to `.has-led` so the text fallback keeps the padding it was
   drawn for. */
.client-marquee.has-led {
  padding: 12px 0;

  /* BLENDED, NOT BANDED.

     refine.css gives this section a surface of its own plus a hairline top and
     bottom — the system's normal way of marking a section. That framing is what
     made the ticker read as a boxed strip bolted under the hero instead of as
     part of it. Both hairlines go, and the surface becomes the hero's own
     (--waves-bg), so the hero runs straight down into the dots with no seam.

     In light this is exact: the hero is #ffffff and so was this section, so the
     hairline was the ONLY thing dividing them. In dark it is the real fix — the
     section was #1d1d1f against a black hero, and matching it is what removes
     the step.

     The tone change now happens where the next chapter's canvas begins, which
     is an ordinary section boundary and needs no line to be legible. */
  background: var(--waves-bg);
  border-top: 0;
  border-bottom: 0;
}

/* The last line. `.hero-scene` carries a bottom hairline of its own
   (css/hero-scene.css), which used to be the join between the hero and this
   band. Now that the two are one surface it is a rule drawn through the middle
   of a continuous block — the exact seam the borders above were removed to get
   rid of. It only exists on the homepage, which is the only page with either of
   these two sections. */
.hero-scene:has(+ .client-marquee.has-led) { border-bottom: 0; }

.client-marquee-led {
  position: relative;
  /* An explicit height: the canvas is `height: 100%` of its host, and a host
     that sizes to its content would collapse to zero. */
  height: var(--led-board-h);
  width: 100%;
}

/* The board replaces the track, so the keyframe must not also run — it would
   translate the canvas out of the section while the component scrolls the dots
   inside it. */
.client-marquee.has-led .client-marquee-track {
  animation: none;
  transform: none;
}

/* The names, kept for assistive tech and crawlers only. Not `display: none`
   and not `visibility: hidden` — both drop the text out of the accessibility
   tree, which is the one thing this element still exists to be in. */
.client-marquee.has-led .client-marquee-track {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

/* --------------------------------------------------------------------------
   Where it stands down

   No canvas, no board — js/effects/led-marquee.js leaves `.has-led` off and the
   original CSS track runs exactly as it did. Nothing here needs a fallback.
   -------------------------------------------------------------------------- */

/* A phone gets a smaller board and a tighter band. js/effects/led-marquee.js re-reads
   these on resize, so crossing the breakpoint mid-session re-sizes the grid
   rather than just cropping the canvas. */
@media (max-width: 700px) {
  :root {
    --led-board-h: 20px;
    --led-text-size: 15;
    --led-dot-size: 1.7;
  }
  .client-marquee.has-led { padding: 8px 0; }
}


/* ==========================================================================
   Reduced motion
   A continuously scrolling band is the motion type most likely to trigger
   symptoms, and this stylesheet was one of four with no guard. The board
   still reads — it just holds still.
   ========================================================================== */
@media (prefers-reduced-motion: reduce) {
  .client-marquee-track,
  .client-marquee-led,
  .client-marquee canvas {
    animation: none !important;
    transition: none !important;
  }
  .client-marquee-track { transform: none !important; }
}
