/* ==========================================================================
   STRATA — "the page is being printed"

   One mechanism, not a set of reveals. Each .stratum on the landing page is
   laid down the way the machine lays a part: in horizontal bands, from the
   section's bottom edge upward, with the hot nozzle line leading the fill and
   cooling behind it.

   Three properties carry the whole thing:

     --print   how far up the section the material has been laid. Quantised to
               16 bands with steps(), so material arrives a stratum at a time
               rather than fading in.
     --heat    the nozzle. Flashes as each band is deposited and decays until
               the head moves up — a sawtooth, one tooth per band.
     view()    the driver. The animation is *scrubbed by scroll position*, not
               triggered by an intersection, so scrubbing back up un-prints the
               section. That is what makes it read as a machine.

   SAFETY — read before editing.
   The resting state of the page is "fully printed". Nothing here may leave
   content hidden:
     · the entire effect lives inside @supports (animation-timeline: view()),
       so a browser without scroll-driven animations never sees a mask at all;
     · it is additionally gated on (prefers-reduced-motion: no-preference), so
       the reduce preference gets the plain page rather than a frozen one — the
       global `animation-duration: .001ms !important` in styles.css would
       otherwise pin a scroll-driven animation at its `from` keyframe;
     · the registered initial values are --print: 100% / --heat: 0, i.e. laid
       and cold, so even a half-applied cascade renders the page complete;
     · :focus-within drops the mask outright, so keyboard focus can never land
       inside material that has not been laid yet.

   No transforms, no layout properties and no `will-change` — the effect cannot
   shift layout, and it leaves nothing promoted behind once it has run.
   ========================================================================== */

@property --print {
  syntax: "<length-percentage>";
  inherits: false;
  initial-value: 100%;          /* resting state: fully laid */
}
@property --heat {
  syntax: "<number>";
  inherits: false;
  initial-value: 0;             /* resting state: nozzle cold, no amber */
}

@keyframes strata-lay {
  from { --print: 0%; }
  to   { --print: 100%; }
}

/* One tooth per band: full heat the instant a band is deposited, decaying
   while the head dwells on it, then the head steps up and it flashes again.
   The last four teeth taper so the pass ends cold instead of being cut off. */
@keyframes strata-nozzle {
  0%      { --heat: 1; }
  6.23%   { --heat: 0.2; }
  6.25%   { --heat: 1; }
  12.48%  { --heat: 0.2; }
  12.5%   { --heat: 1; }
  18.73%  { --heat: 0.2; }
  18.75%  { --heat: 1; }
  24.98%  { --heat: 0.2; }
  25%     { --heat: 1; }
  31.23%  { --heat: 0.2; }
  31.25%  { --heat: 1; }
  37.48%  { --heat: 0.2; }
  37.5%   { --heat: 1; }
  43.73%  { --heat: 0.2; }
  43.75%  { --heat: 1; }
  49.98%  { --heat: 0.2; }
  50%     { --heat: 1; }
  56.23%  { --heat: 0.2; }
  56.25%  { --heat: 1; }
  62.48%  { --heat: 0.2; }
  62.5%   { --heat: 1; }
  68.73%  { --heat: 0.2; }
  68.75%  { --heat: 1; }
  74.98%  { --heat: 0.2; }
  75%     { --heat: 0.82; }
  81.23%  { --heat: 0.164; }
  81.25%  { --heat: 0.6; }
  87.48%  { --heat: 0.12; }
  87.5%   { --heat: 0.38; }
  93.73%  { --heat: 0.076; }
  93.75%  { --heat: 0.18; }
  99.98%  { --heat: 0.036; }
  100%    { --heat: 0; }
}

/* `mask-clip: no-clip` is required, not cosmetic: the eyebrow label hangs
   4.5px above the section's box (it sits *on* the rule), and a default
   border-box mask clip would shear it in half for good. Requiring it here also
   guarantees the unprefixed mask longhands, which landed alongside it. */
@supports (animation-timeline: view()) and (mask-clip: no-clip) {
  @media (prefers-reduced-motion: no-preference) {

    .stratum {
      /* The band boundary. Hard below, an 11px molten ramp above — a print
         edge is not a fade, but it is not a razor cut through a glyph either.
         The mask box is grown 22px upward (and re-anchored) so the overhanging
         eyebrow label is inside it; the same +22px/-22px geometry is repeated
         on the nozzle layer below so both resolve their percentages against
         exactly the same box. */
      mask-image: linear-gradient(
        to top,
        #000 0 var(--print),
        rgba(0, 0, 0, .55) calc(var(--print) + 3px),
        rgba(0, 0, 0, 0)   calc(var(--print) + 11px));
      mask-repeat: no-repeat;
      mask-origin: padding-box;
      mask-clip: no-clip;
      mask-size: 100% calc(100% + 22px);
      mask-position: 0 -22px;

      view-timeline-name: --stratum-print;

      /* jump-start: the band lands at the *start* of its interval, so the
         nozzle flash and the material it deposits happen on the same frame. */
      animation: strata-lay linear both;
      animation-timing-function: steps(16, jump-start);
      animation-timeline: --stratum-print;
      animation-range: entry 4% entry 72%;
    }

    /* The nozzle pass. Painted above the content but inside the section's own
       mask, so the head never draws on material that has not been laid.
       `--print` is re-animated here rather than inherited: an inherited
       registered property would force a style recalc on every descendant of
       every section on every frame. */
    .stratum::after {
      content: "";
      position: absolute;
      inset: 0;
      z-index: 3;
      pointer-events: none;
      /* The pass: a hairline at the edge, and the material just below it still
         cooling. The cooling tail is capped at .10 alpha — it composites over
         live text for as long as the head is on that band, and .10 is the
         measured ceiling that keeps every text element inside a stratum above
         4.5:1 (worst case 4.88:1, the 11px "Empfohlen" badge). The hairline
         itself is 1.25px: it crosses glyphs, it is never their background. */
      background-image: linear-gradient(
        to top,
        rgba(245, 165, 36, 0)    calc(var(--print) - 40px),
        rgba(245, 165, 36, .035) calc(var(--print) - 24px),
        rgba(245, 165, 36, .10)  calc(var(--print) - 6px),
        rgba(245, 165, 36, .90)  calc(var(--print) - 1.25px),
        rgba(245, 165, 36, .90)  var(--print),
        rgba(245, 165, 36, .20)  calc(var(--print) + 4px),
        rgba(245, 165, 36, 0)    calc(var(--print) + 10px));
      background-repeat: no-repeat;
      background-size: 100% calc(100% + 22px);
      background-position: 0 -22px;
      opacity: var(--heat);

      animation: strata-lay linear both, strata-nozzle linear both;
      animation-timing-function: steps(16, jump-start), linear;
      animation-timeline: --stratum-print, --stratum-print;
      animation-range: entry 4% entry 72%, entry 4% entry 72%;
    }

    /* Escape hatch. Focus can be moved by the keyboard into a region the head
       has not reached; rather than leave an invisible focus ring, the section
       finishes printing immediately. */
    .stratum:focus-within {
      mask-image: none;
    }
    .stratum:focus-within::after {
      opacity: 0;
    }
  }
}
