/* =========================================================================
   dot-wave.css — the band the dot wave is drawn into
   -------------------------------------------------------------------------
   The two rules that give /dot-wave.js somewhere to draw: a full-bleed band
   and the canvas filling it. Shared by all four pages as of 4 Sep 2026.

   Before that they existed three times - account.css lines 571-624 for
   /account and /admin, and inline in index.html and request.html, which do
   not load account.css. dot-wave.js's own header said its CSS "lives in
   account.css - so any page already linking that file has them", which was
   true of the two pages that linked it and quietly wrong about the two that
   did not. That header is corrected in the same change as this file.

   Extracting the JS without the CSS would have left the module drawing into
   a box defined three different times. It is the same lesson buttons.css
   was created for a day earlier: a component is its markup, its script AND
   its CSS, and whichever of the three cannot travel is the one that breaks.

   The declarations below are byte-identical across all three former copies -
   they never drifted. Only the comments differed, and the fullest version of
   each is the one kept here.

   TOKENS: none. This file references no custom properties at all, so there
   is nothing for a page to be missing. The colours are the canvas's problem,
   and dot-wave.js reads --accent-rgb / --light-rgb for them itself.
   ========================================================================= */

  /* Own section, own fixed height, living entirely below the footer as
     ordinary block content inside <main> (see the HTML after the footer).
     Nothing fancy is needed to make it "fade in from nothing" at its own top
     edge - the animation's existing per-row alpha (dot-wave.js's draw(), the
     `dot.t` term) already goes from barely-there at the top of the band to
     fully visible toward the bottom, which is exactly the sparse-to-dense
     look in the reference screenshot. No extra fade layer required; the
     effect was already built in. */
  .wave-band {
    /* Lives inside <main>, but <main> is capped at --content-w (a narrow
       centered column) with its own side padding. width: 100% here used to
       mean "100% of that narrow column," not the actual browser width -
       that's why the animation was truncated horizontally on desktop. This
       is the standard full-bleed breakout: 100vw + negative half-viewport
       margins pulls the band out past its parent's constraints so it always
       spans the full browser width, no matter how narrow <main> itself is.
       Height is untouched. */
    position: relative;
    left: 50%;
    right: 50%;
    width: 100vw;
    margin-left: -50vw;
    margin-right: -50vw;
    /* svh, not vh — Carson's report: an iPad Pro (M1) in landscape, Safari
       specifically, was showing an extra strip of the page's own themed
       background below the dots, portrait unaffected. Plain vh is exactly
       the kind of value that's unstable in Mobile Safari — it can resolve
       based on a toolbar state that hasn't fully settled yet, especially
       right after an orientation change, and #bg-wave's own resize() reads
       this box's actual clientHeight and bakes it into the canvas at that
       moment — so any instability here becomes a real, visible mismatch
       between what the canvas drew and what the CSS box actually ends up
       being, not just a rounding difference.

       account.html's .stack-wrap hit this same underlying class of bug
       already (see its own comment in account.css for the fuller history —
       three earlier fixes tried there, including one that used dvh
       specifically, before landing on svh as the one that actually holds
       up) and settled on svh for the identical reason: by spec it's always
       computed against the browser's UI chrome in its MAXIMALLY EXPANDED
       state, correct from the very first paint, no later re-settling to
       race against. dvh was deliberately ruled out THERE for a
       well-documented WebKit bug where it doesn't reliably re-evaluate back
       down after the toolbar re-expands — not used here either, for the
       same reason.

       This was never previously wired up to svh in index.html's own
       history — the earlier "fixed this before" was almost certainly
       account.html's version of the same underlying issue, not literally
       this element regressing, though the visible symptom and the actual
       fix are the same either way. account.css's copy carried a note that
       it had been applied there proactively rather than waiting for the
       same bug to be noticed separately on that page; sharing one rule is
       what that note was reaching for. */
    /* vh first, svh second, and the pair is load-bearing. An engine that
       does not understand `svh` drops that whole declaration as invalid
       and falls back to this line; one that does understand it takes the
       second and behaves exactly as documented above. Without the
       fallback the band gets height:auto, which is ZERO here — its only
       child is position:absolute — and the canvas is then sized to 0.
       That used to fail silently (arc() and fill() do not mind a
       zero-sized canvas), but drawImage() throws on a zero-sized source,
       and the sunbather is composited from one. */
    height: clamp(160px, 24vh, 260px);
    height: clamp(160px, 24svh, 260px);
    margin-top: 20px;
    overflow: hidden;
  }
  #bg-wave {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    pointer-events: none;
  }
  /* The band goes entirely, rather than the canvas being left blank inside
     it: dot-wave.js also refuses to start under reduced motion (it returns
     {started:false, reason:"reduced-motion"}), so an empty band would be
     20px of margin and up to 260px of nothing. */
  @media (prefers-reduced-motion: reduce) {
    .wave-band { display: none; }
  }
