/* ===============================================================
   OIL-SLICK DRIP — the layer the background canvas lives in.

   Companion to assets/js/oil-drip.js. Front page only; enqueue both
   behind is_front_page() so the twenty-four tool-page URLs never even
   download them.

   THE MARKUP THIS EXPECTS (a direct child of <body>, so nothing can
   clip it — front-page.php, immediately after get_header()):

       <div class="gz-oil-drip" aria-hidden="true">
           <canvas id="gz-oil-drip-canvas"></canvas>
       </div>

   It is decoration with no content, so aria-hidden and no label: there
   is nothing here for a screen reader to announce.
   =============================================================== */

.gz-oil-drip {
  /* Fixed, not absolute. The drip is a backdrop the page scrolls over,
     the way the simulator's canvas sat still under its overlay — and it
     means the shader only ever covers one viewport, not the full height
     of a long landing page.

     top/right/bottom/left rather than 100vw/100vh: 100vw includes the
     scrollbar gutter and would push the canvas sideways.

     z-index -1 is what puts it BEHIND static content. The sections and
     the copy are not positioned, so at z-index 0 this layer would paint
     over them; below zero it paints above the page background and under
     everything else. The sticky .gz-header (z-index 50) and the hero's
     blurred blooms keep sitting on top, which is the intent. */
  position: fixed;
  top: 0; right: 0; bottom: 0; left: 0;
  z-index: -1;

  /* IT IS A BACKGROUND, NOT A CEILING. Nothing in this layer may take a
     click, a tap or a scroll. The JS listens on window instead. */
  pointer-events: none;

  /* WHAT MAKES z-index -1 VISIBLE AT ALL: style.css puts the page
     background on `body` and nothing on `html`, so it propagates to the
     viewport canvas and body's own box paints nothing. A layer below zero
     therefore lands ABOVE the page ground and below the content. Give
     `html` a background of its own and body's would start painting on its
     own box instead — over this layer, and the drip disappears with no
     error anywhere. Nothing else in the theme is positioned at the root,
     and no section sets a background, so the drip shows through the whole
     page and the opaque cards and panels sit on top of it.

     The theme's own ground, painted underneath. If the canvas never gets
     a context, or the browser paints this layer under the body
     background instead of over it, what shows is the same #0B0B0F the
     page has always had. */
  background: var(--gz-void);
}

.gz-oil-drip canvas {
  display: block;
  width: 100%;
  height: 100%;
}

/* THE SCRIM — this is what keeps the body copy readable.
   ---------------------------------------------------------------
   Measured, not guessed. With both intensities frozen at 0.20 the
   brightest pixel the shader can emit is a gold crest at NdotL = 1:
   blendFactor tops out at 0.40 and darkShade at 0.702, which lands on
   rgb(82,64,34), L = 0.0556. Text over THAT, unscrimmed:

       --gz-text  (#EDEAF2)   8.35:1   fine
       --gz-muted (#9B96A8)   3.47:1   FAILS AA
       --gz-faint (#66626F)   1.68:1   fails, but see below

   --gz-muted is the lede, the section intros, the nav. It reads 6.85:1
   on the calm surface and only falls apart under a crest — i.e. it
   passes every check until a wave happens to drift behind a paragraph,
   which is the worst possible way to find a contrast bug.

   40% of the void over the canvas lifts the same worst-case pixel to
   --gz-muted 4.84:1 and --gz-text 11.68:1, clear of 4.5:1 at every
   scroll position because the scrim is uniform — there is no position
   where it is thinner. Cost: crests lose 40% of their punch, on an
   effect already dialled to the quietest setting the simulator offers.
   Readability wins that trade.

   IF THIS NUMBER IS EVER LOWERED, re-check --gz-muted: below ~0.30 it
   goes under AA on a crest.

   --gz-faint IS NOT FIXABLE FROM HERE. It reads 3.31:1 on today's page
   with no canvas at all — already under AA before any of this — and no
   scrim value rescues it (2.53:1 even at 50%). It needs the token, not
   the layer. In the hero that is .gz-cta-note; --gz-muted would pass. */
.gz-oil-drip::after {
  content: "";
  position: absolute;
  top: 0; right: 0; bottom: 0; left: 0;
  background: rgba(11, 11, 15, .40);
  pointer-events: none;
}

/* NO WEBGL, NO PROBLEM. The JS adds this class when the context cannot
   be created, when a shader fails to compile or link, or when a live
   context is lost. The page falls back to precisely what it looks like
   today: the --gz-void ground and the hero's own blooms. Never a black
   hole where the hero used to be. */
.gz-oil-drip--unavailable {
  display: none;
}
