/* ==========================================================================
   Blob Decorations (v3.2 — outline variant + refactored)
   --------------------------------------------------------------------------
   Three blob decoration types share the same anchor / shape / size / color
   system:

     1) Background blob   .has-blob-bg   (inline SVG injected by JS, fill)
     2) Image mask        .blob-mask     (figure with clip-path)
     3) Outline blob      .blob-outline  (inline SVG injected by JS, stroke)

   Shapes are generated as SVG paths by /js/applari-js/blob-decorations.js.
   This file handles positioning, color, sizing, and the "breathing" pulse.

   USAGE
   -----
   A) Background blob on a .color-section
      <div class="color-section gb-container alignfull
                  has-blob-bg blob-pink blob-anchor-l blob-shape-1">
        ...
      </div>

   B) Image blob mask — TWO MODES
      Mode B1: Flow mode (no anchor → block flow with shape's aspect-ratio)
        <figure class="wp-block-image blob-mask blob-shape-2">
          <img src="..." />
        </figure>

      Mode B2: Anchor mode (any .blob-anchor-* → positioned absolutely)
        <figure class="blob-mask blob-anchor-r blob-shape-7 blob-size-md">
          <img src="..." />
        </figure>

      Anchor mode requires the parent to have .has-blob-bg or .has-blob-decor
      (positioning context).

   C) Outline blob (transparent fill, stroked border, always on top)
      <div class="color-section has-blob-decor">
        <div class="blob-outline blob-anchor-r blob-shape-7 blob-size-lg"></div>
        <h1>...</h1>
      </div>

      Outline always renders on top (z-index: 2) above .has-blob-bg blobs and
      .blob-mask elements. Always anchored. pointer-events: none.

   D) Marker class for sections that have only positioned masks/outlines
      (no background blob):
        <div class="color-section has-blob-decor">...</div>

   Shared modifiers:
     Color    : .blob-pink (default), .blob-green, .blob-blue, .blob-light-blue
     Anchor   : .blob-anchor-l (default), .blob-anchor-r, .blob-anchor-t,
                .blob-anchor-b, .blob-anchor-tl, .blob-anchor-tr,
                .blob-anchor-bl, .blob-anchor-br
     Shape    : .blob-shape-1 (default) … .blob-shape-7
     Size     : .blob-size-md (default, 110%), .blob-size-sm (70%),
                .blob-size-lg (150%), .blob-size-xl (200%)

   Per-section overrides (CSS variables, set inline via style="..."):
     --blob-bg-height     : background blob height %
     --blob-mask-height   : image mask height % (anchor mode only)
     --blob-mask-fill     : image mask scale (default 1). The default path
                            already nearly fills the box, so values > 1
                            cause edge clamping. Override only if you
                            accept straight-edge artifacts.
     --blob-outline-height: outline blob height %
     --blob-outline-width : outline stroke width in CSS px (default 2)
     --blob-overflow      : overhang past anchored edge (default 30%)
     --blob-aspect        : per-shape aspect ratio (auto-set by shape class)

   ARCHITECTURE NOTES
   ------------------
   - Single source of truth for anchor positioning, per-shape aspect ratio,
     color variants, and size presets — all consumed by 3 blob types via
     CSS custom properties.
   - JS injects <svg class="blob-bg-svg"> for backgrounds and
     <svg class="blob-outline-svg"> for outlines. Image masks use a global
     <svg><defs><clipPath> referenced via clip-path: url(#id).
   - Path morphing happens via `transition: d` on the SVG <path>.
   - 12s morph + 12s pulse, intentionally calm.
   ========================================================================== */


/* --------------------------------------------------------------------------
   1. Positioning context (parent of any blob decoration)
   --------------------------------------------------------------------------
   .has-blob-bg always provides this context (it has its own background blob).
   .has-blob-decor is the marker for sections that have only positioned
   masks or outlines — no background blob.
   -------------------------------------------------------------------------- */
    :root{
        --pink: #FFE2FC;
    }
   .has-blob-bg,
   .has-blob-decor {
       position: relative;
       isolation: isolate;
   
       --blob-overflow: 15%;
       overflow-x: clip;
   }
   
   
   /* --------------------------------------------------------------------------
      2. Shared variables — single source of truth
      --------------------------------------------------------------------------
      These CSS custom properties are unscoped, so they can live on either the
      parent (.has-blob-bg) or the consumer itself (.blob-mask, .blob-outline)
      and inherit to wherever the consumer reads them. Setting them on a
      non-blob element has no side effects.
      -------------------------------------------------------------------------- */
   
   /* Color variants */
   .blob-pink       { --blob-color: #FFE2FC; }
   .blob-green      { --blob-color: var(--green); }
   .blob-blue       { --blob-color: var(--blue); }
   .blob-light-blue { --blob-color: var(--light-blue); }
   
   /* Per-shape aspect ratios — width = height × aspect */
   .blob-shape-1 { --blob-aspect: 1.10 / 1; }
   .blob-shape-2 { --blob-aspect: 1.40 / 1; }
   .blob-shape-3 { --blob-aspect: 1.00 / 1; }
   .blob-shape-4 { --blob-aspect: 0.85 / 1; }
   .blob-shape-5 { --blob-aspect: 1.05 / 1; }
   .blob-shape-6 { --blob-aspect: 1.05 / 1; }
   .blob-shape-7 { --blob-aspect: 1.45 / 1; }
   
   /* Size presets — height as % of parent section. Per-blob-type overrides
      (--blob-bg-height etc.) take precedence as inline styles. */
   .blob-size-sm { --blob-h: 70%; }
   .blob-size-md { --blob-h: 110%; }
   .blob-size-lg { --blob-h: 150%; }
   .blob-size-xl { --blob-h: 200%; --blob-overflow: 35%; }
   
   /* Image mask fill — scales the clip-path outward from the center.
      Default 1.0 = the generated path already nearly fills the box (max extent
      ~0.48 of a 0..1 unit box). Values > 1.0 push the path past the box edge,
      which causes the clip-path to clamp to the figure's bounding box →
      straight edges along the clipped sides. Override per-element only if you
      accept that trade-off:
        <figure class="blob-mask blob-shape-7" style="--blob-mask-fill: 1.1;"> */
   
   
   /* --------------------------------------------------------------------------
      3. A) Background blob — inline SVG injected by JS into .has-blob-bg
      -------------------------------------------------------------------------- */
   
   .has-blob-bg .blob-bg-svg {
       position: absolute;
       z-index: -1;
       pointer-events: none;
   
       height: var(--blob-bg-height, var(--blob-h, 110%));
       width: auto;
       aspect-ratio: var(--blob-aspect, 1.10 / 1);
   
       color: var(--blob-color, var(--grey));
   
       /* Default position equivalent to .blob-anchor-l. Anchor classes below
          override this. */
       top: 50%;
       left: 0;
       translate: calc(-1 * var(--blob-overflow)) -50%;
   }
   
   
   /* --------------------------------------------------------------------------
      4. B) Image blob mask — applies to <figure> wrapping an <img>
      --------------------------------------------------------------------------
      JS sets clip-path: url(#blob-clip-N) and morphs the underlying <path> d
      attribute. Two modes:
      - Flow mode (no anchor class): figure adopts the shape's aspect-ratio and
        crops the image via object-fit: cover.
      - Anchor mode (any .blob-anchor-*): figure becomes positioned absolutely
        inside its parent, like a background blob.
      -------------------------------------------------------------------------- */
   
   .blob-mask {
       aspect-ratio: var(--blob-aspect, auto);
   }
   
   .blob-mask img {
       display: block;
       width: 100%;
       height: 100%;
       object-fit: cover;
   }
   
   /* Anchor mode — pulls the figure out of flow */
   .blob-mask:is(.blob-anchor-l, .blob-anchor-r, .blob-anchor-t, .blob-anchor-b,
                 .blob-anchor-tl, .blob-anchor-tr, .blob-anchor-bl, .blob-anchor-br) {
       position: absolute;
       z-index: -1;
       pointer-events: none;
       margin: 0;
   
       height: var(--blob-mask-height, var(--blob-h, 110%));
       width: auto;
   }
   
   
   /* --------------------------------------------------------------------------
      5. C) Outline blob — inline SVG injected by JS into .blob-outline
      --------------------------------------------------------------------------
      Transparent fill, stroked path. Always positioned absolutely (anchor
      class required), always on top of other blobs (z-index: 2). Click events
      pass through (pointer-events: none).
   
      Stroke width is controlled by --blob-outline-width (default 2px). The JS
      sets vector-effect="non-scaling-stroke" so the stroke stays a constant
      pixel width regardless of the SVG viewBox scaling.
      -------------------------------------------------------------------------- */
   
   .blob-outline {
       position: absolute;
       z-index: 1;
       pointer-events: none;
       margin: 0;
   
       height: var(--blob-outline-height, var(--blob-h, 110%));
       width: auto;
       aspect-ratio: var(--blob-aspect, 1.10 / 1);
   
       color: var(--blob-color, var(--pink));
   
       /* Default position equivalent to .blob-anchor-l. Anchor classes below
          override this. */
       top: 50%;
       left: 0;
       translate: calc(-1 * var(--blob-overflow)) -50%;
   }
   
   .blob-outline .blob-outline-svg {
       width: 100%;
       height: 100%;
       display: block;
   }
   
   
   /* --------------------------------------------------------------------------
      6. Shared anchor positioning — single source of truth
      --------------------------------------------------------------------------
      Each anchor pins the blob to one edge or corner of the parent and pushes
      it `--blob-overflow` past that edge. Translate percentages refer to the
      blob's own width/height, so overhang scales with blob size.
      -------------------------------------------------------------------------- */
   
   /* Edge: left */
   .has-blob-bg.blob-anchor-l .blob-bg-svg,
   .blob-mask.blob-anchor-l,
   .blob-outline.blob-anchor-l {
       top: 50%;    bottom: auto;
       left: 0;     right: auto;
       translate: calc(-1 * var(--blob-overflow)) -50%;
   }
   
   /* Edge: right */
   .has-blob-bg.blob-anchor-r .blob-bg-svg,
   .blob-mask.blob-anchor-r,
   .blob-outline.blob-anchor-r {
       top: 50%;    bottom: auto;
       left: auto;  right: 0;
       translate: var(--blob-overflow) -50%;
   }
   
   /* Edge: top */
   .has-blob-bg.blob-anchor-t .blob-bg-svg,
   .blob-mask.blob-anchor-t,
   .blob-outline.blob-anchor-t {
       top: 0;      bottom: auto;
       left: 50%;   right: auto;
       translate: -50% calc(-1 * var(--blob-overflow));
   }
   
   /* Edge: bottom */
   .has-blob-bg.blob-anchor-b .blob-bg-svg,
   .blob-mask.blob-anchor-b,
   .blob-outline.blob-anchor-b {
       top: auto;   bottom: 0;
       left: 50%;   right: auto;
       translate: -50% var(--blob-overflow);
   }
   
   /* Corner: top-left */
   .has-blob-bg.blob-anchor-tl .blob-bg-svg,
   .blob-mask.blob-anchor-tl,
   .blob-outline.blob-anchor-tl {
       top: 0;      bottom: auto;
       left: 0;     right: auto;
       translate: calc(-1 * var(--blob-overflow)) calc(-1 * var(--blob-overflow));
   }
   
   /* Corner: top-right */
   .has-blob-bg.blob-anchor-tr .blob-bg-svg,
   .blob-mask.blob-anchor-tr,
   .blob-outline.blob-anchor-tr {
       top: 0;      bottom: auto;
       left: auto;  right: 0;
       translate: var(--blob-overflow) calc(-1 * var(--blob-overflow));
   }
   
   /* Corner: bottom-left */
   .has-blob-bg.blob-anchor-bl .blob-bg-svg,
   .blob-mask.blob-anchor-bl,
   .blob-outline.blob-anchor-bl {
       top: auto;   bottom: 0;
       left: 0;     right: auto;
       translate: calc(-1 * var(--blob-overflow)) var(--blob-overflow);
   }
   
   /* Corner: bottom-right */
   .has-blob-bg.blob-anchor-br .blob-bg-svg,
   .blob-mask.blob-anchor-br,
   .blob-outline.blob-anchor-br {
       top: auto;   bottom: 0;
       left: auto;  right: 0;
       translate: var(--blob-overflow) var(--blob-overflow);
   }
   /*Centered blob*/
   .has-blob-bg.blob-anchor-center .blob-bg-svg,
   .blob-mask.blob-anchor-center,
   .blob-outline.blob-anchor-center {
       --blob-overflow: 0%;
       top: 50%;
       left: 50%;
       translate: -50% -50%;
   }
   /*Centered bottom blob*/
   .has-blob-bg.blob-anchor-center-bottom .blob-bg-svg,
   .blob-mask.blob-anchor-center-bottom,
   .blob-outline.blob-anchor-center-bottom {
       top: auto;
       bottom: 0;
       left: 50%;
       translate: -50% 0;
   }
   
   
   /* --------------------------------------------------------------------------
      7. Animations — pulse + path morph, all blob types
      --------------------------------------------------------------------------
      Linear easing on path morph paired with the synced 12s JS interval gives
      continuous, uniform motion without slow zones at cycle boundaries.
      Pulse is intentionally subtle (4% scale) and slow.
      -------------------------------------------------------------------------- */
   
   .blob-bg-svg,
   .blob-mask,
   .blob-outline {
       animation: blob-pulse 24s ease-in-out infinite alternate;
   }
   
   .blob-bg-svg path,
   .blob-outline .blob-outline-svg path,
   svg defs clipPath path {
       transition: d 24s linear;
   }
   
   @keyframes blob-pulse {
       from { scale: 1; }
       to   { scale: 1.04; }
   }
   
   
   
   
   /* --------------------------------------------------------------------------
      8. Mobile responsiveness — cap blob dimensions on small viewports
      --------------------------------------------------------------------------
      On narrow viewports a tall mobile section makes the height-based blob
      grow much taller than the viewport, and with wide aspect-ratio shapes
      the resulting width can be several times the viewport width — leaving
      only a thin vertical slice visible after the anchor's overhang.
   
      These caps prevent the blob from outgrowing reasonable viewport bounds.
      With aspect-ratio set, the unbound dimension shrinks to maintain shape
      proportions, so the blob stays recognizable.
      -------------------------------------------------------------------------- */
   
   @media (max-width: 768px) {
       .has-blob-bg .blob-bg-svg,
       .blob-mask:is(.blob-anchor-l, .blob-anchor-r, .blob-anchor-t, .blob-anchor-b,
                     .blob-anchor-tl, .blob-anchor-tr, .blob-anchor-bl, .blob-anchor-br),
       .blob-outline {
           max-width: 170vw;
       }
       /*Wider blob in mobile*/
       .has-blob-bg.wider-blob-in-mobile .blob-bg-svg,
       .has-blob-bg .wider-blob-in-mobile.blob-mask,
       .has-blob-bg .wider-blob-in-mobile.blob-outline{
           max-width: 250vw;
       }
   }
   
   
   /* --------------------------------------------------------------------------
      9. Reduced motion — disable pulse and morph transition
      -------------------------------------------------------------------------- */
   
   @media (prefers-reduced-motion: reduce) {
       .blob-bg-svg,
       .blob-mask,
       .blob-outline {
           animation: none;
       }
   
       .blob-bg-svg path,
       .blob-outline .blob-outline-svg path,
       svg defs clipPath path {
           transition: none;
       }
   }
   /* --------------------------------------------------------------------------
      10. Fade-in on scroll — opacity 0 → 1 when blob enters the viewport
      --------------------------------------------------------------------------
      JS adds .is-blob-visible to .has-blob-bg / .has-blob-decor / .blob-mask
      via IntersectionObserver. Above-the-fold elements become visible on load;
      below-the-fold elements fade in as they scroll into view.
   
      Only active for users who have no motion preference — reduced-motion users
      always see blobs at full opacity.
      -------------------------------------------------------------------------- */
   
   @media (prefers-reduced-motion: no-preference) {
       .blob-bg-svg,
       .blob-mask,
       .blob-outline {
           opacity: 0;
           transition: opacity 0.8s ease;
       }
   
       .is-blob-visible .blob-bg-svg,
       .is-blob-visible .blob-mask,
       .is-blob-visible .blob-outline,
       .blob-mask.is-blob-visible {
           opacity: 1;
       }
   }
   .editor-styles-wrapper .blob-bg-svg,
   .editor-styles-wrapper .blob-mask,
   .editor-styles-wrapper .blob-outline,
   .editor-styles-wrapper .blob-mask.is-blob-visible {
       opacity: 1;
   }
   .editor-styles-wrapper .is-blob-visible .blob-bg-svg,
   .editor-styles-wrapper .is-blob-visible .blob-mask,
   .editor-styles-wrapper .is-blob-visible .blob-outline,
   .editor-styles-wrapper .blob-mask.is-blob-visible {
       opacity: 1;
   }
   
   
   /*Helper classes*/
   .has-blob-bg.offset-blob-left .blob-bg-svg,
   .has-blob-bg.offset-blob-left .blob-mask,
   .has-blob-bg .offset-blob-left.blob-outline{
       left:-25%;
   }
   .has-blob-bg.offset-blob-right .blob-bg-svg,
   .has-blob-bg.offset-blob-right .blob-mask,
   .has-blob-bg .offset-blob-right .blob-outline{
       right:-25%;
   }
   .has-blob-bg.offset-blob-top .blob-bg-svg,
   .has-blob-bg.offset-blob-top .blob-mask,
   .has-blob-bg .offset-blob-top .blob-outline{
       top:-50%;
   }
   .has-blob-bg.offset-blob-bottom .blob-bg-svg,
   .has-blob-bg.offset-blob-bottom .blob-mask,
   .has-blob-bg .offset-blob-bottom .blob-outline{
       translate:-50% 50%;
   }