/* ============================================================
   Phantom Lab: BACKDROP
   ------------------------------------------------------------
   Decorative "deep space" background for everything below the
   hero, built to read as DEPTH rather than as a flat tint.
   Pure CSS: gradients only, no canvas, no JS, no images.

   HARD RULE: every layer here belongs to a section, so it scrolls with
   the content it decorates. Nothing on this page is painted onto a
   viewport-fixed layer any more. Fixed decoration holds still while the
   page slides through it, and at these alphas the eye reads that as
   dirt or film on the screen rather than as depth; that is what
   retired the star field, the constellations, the aurora and the
   colour blobs, in that order.

   Layer stack, from far to near:

     .section-zone      ---    (element itself, no paint)
     .section-zone::before     zone glows (big soft blobs)
     .section-zone::after      structure (wells, orbits, beams), no stars
     .section > .container     REAL CONTENT (z-index: 1)

   Perf notes
   ----------
   * Every decorative gradient that is not meant to tile is given
     an explicit `/ <size> no-repeat` so the rasteriser only ever
     touches that sub-rectangle instead of the whole (up to
     2500px tall) section box. This is what makes ~20 background
     layers per section affordable.
   * Nothing here animates `background-position` any more, that
     forced a full repaint of every layer on every frame. The one
     remaining animation is a `transform: rotate()` on a single
     fixed element, which the compositor handles for free.
   * All layers are `pointer-events: none` and sit below the
     content's own `z-index: 1`.

   Contrast
   --------
   Peak blob alphas are capped so the composited backdrop stays
   below ~0.026 relative luminance in dark mode and above ~0.75
   in light mode; that keeps --text-muted (the weakest text on
   the page) at >=4.5:1 everywhere. Peaks are also positioned
   into the outer margins, never behind a text column.
   ============================================================ */

:root {
  --bd-v: 124, 58, 237;   /* violet */
  --bd-b: 79, 124, 255;   /* blue   */
  --bd-c: 34, 211, 238;   /* cyan   */

  /* Glow intensity ramp, g1 is the "hero strength" lead blob. */
  --bd-g1: 0.185;
  --bd-g2: 0.135;
  --bd-g3: 0.10;
  --bd-g4: 0.065;

  /* Thin structural detail (orbits, beams, horizon bands). */
  --bd-ring: rgba(168, 196, 255, 0.048);
  --bd-ring-soft: rgba(168, 196, 255, 0.026);
  --bd-beam: 0.07;
  --bd-horizon: 0.09;

  /* "Content well": a soft darkening (dark theme) / lightening (light
     theme) ellipse painted OVER the zone glows and UNDER the content.
     It buys back the contrast the richer glows cost, and it is what lets
     the outer thirds of every section stay strongly coloured, the eye
     reads it as depth, the text reads it as a calm surface. */
  --bd-well: rgba(4, 7, 16, 0.52);
  --bd-well-mid: rgba(4, 7, 16, 0.33);

  /* No star, vignette or aurora tokens live here any more: every layer that
     was anchored to the viewport has been removed. */
}

[data-theme="light"] {
  /* Light surface: the same composition, an order of magnitude
     softer, and biased to saturated hues so it never turns into
     a grey smudge. */
  --bd-g1: 0.115;
  --bd-g2: 0.085;
  --bd-g3: 0.065;
  --bd-g4: 0.045;

  --bd-ring: rgba(58, 84, 168, 0.05);
  --bd-ring-soft: rgba(58, 84, 168, 0.028);
  --bd-beam: 0.05;
  --bd-horizon: 0.06;

  /* On a light surface the well works the other way round: it lifts the
     centre back to near-white so body copy keeps its ratio. */
  --bd-well: rgba(255, 255, 255, 0.5);
  --bd-well-mid: rgba(255, 255, 255, 0.26);

}

/* ============================================================
   1. GLOBAL FIXED LAYERS  (inside #pageBg → z-index: -1,
      overflow: hidden, contain: paint, cannot overflow)
   ============================================================ */

/* There are no global fixed layers left. Everything that used to be painted
   here, the aurora conic wash and the vignette, was anchored to the
   viewport, so it held still while the page scrolled through it and read as
   a film over the screen rather than as depth. #pageBg now carries only the
   comet (see base.css), and the entire backdrop is built per section below,
   where it travels with the content it belongs to. */

/* ============================================================
   2. PER-SECTION LAYERS
   ============================================================ */

.section-zone {
  isolation: isolate;
}

/* ---- 2a. Zone glows.
   Geometry comes from base.css (.section-zone::before: 100% wide,
   130% tall, top: -15%) so the layer already overhangs the section
   on both sides and colour bleeds across the boundary. The
   border-radius: 50% clip from base.css is dropped here because
   this layer no longer holds one centred ellipse but several
   off-centre blobs, each of which is a *bounded* gradient box that
   fades to fully transparent inside itself, so removing the clip
   cannot introduce an edge.

   HARD RULE for this layer: every blob's gradient box must lie
   FULLY INSIDE the ::before box vertically. There is no mask here,
   so a box that starts above the top (`top -180px`) or ends below
   the bottom (`bottom -120px`) is cut by the element edge, and the
   cut lands mid-ramp where the blob is still 3-5% opaque, that is
   a straight horizontal line across the section boundary, which is
   exactly what the owner saw under the pinned demo. Use percentage
   offsets (`top 0%` / `bottom 0%` at the extremes) and let the 26%
   overhang do the off-canvas centring instead.
   ::after may overhang, because its mask is already 0 at its own
   top and bottom edges, so a cut there is invisible. ---- */
.section-zone::before {
  border-radius: 0;
  height: 152%;
  top: -26%;
}

/* Zone A: services, contact. Violet-led, continues .hero-glow-1
   at the top-right and .hero-glow-2 (cyan) at the top-left, so the
   hero → services boundary reads as one continuous field. */
.zone-a::before {
  background:
    radial-gradient(closest-side circle,
      rgba(var(--bd-v), var(--bd-g1)) 0%,
      rgba(var(--bd-v), calc(var(--bd-g1) * 0.62)) 30%,
      rgba(var(--bd-v), calc(var(--bd-g1) * 0.22)) 58%,
      transparent 100%)
      right -200px top 2% / 1020px 1020px no-repeat,
    radial-gradient(closest-side circle,
      rgba(var(--bd-c), var(--bd-g3)) 0%,
      rgba(var(--bd-c), calc(var(--bd-g3) * 0.45)) 42%,
      transparent 100%)
      left -240px top 6% / 760px 760px no-repeat,
    /* kept one step down the ramp and pushed further off-canvas: the last
       services card and the contact form's small print sit right here, and
       both use the page's weakest text colours. */
    radial-gradient(closest-side circle,
      rgba(var(--bd-b), var(--bd-g3)) 0%,
      rgba(var(--bd-b), calc(var(--bd-g3) * 0.45)) 40%,
      transparent 100%)
      left -300px bottom 12% / 880px 880px no-repeat,
    radial-gradient(closest-side circle,
      rgba(var(--bd-v), var(--bd-g4)) 0%,
      transparent 100%)
      right -200px bottom 4% / 640px 640px no-repeat;
}

/* Zone B: demo, why. Blue/cyan, mirrored: mass on the left at the
   top and on the right at the bottom. */
.zone-b::before {
  background:
    radial-gradient(closest-side circle,
      rgba(var(--bd-b), var(--bd-g1)) 0%,
      rgba(var(--bd-b), calc(var(--bd-g1) * 0.58)) 32%,
      rgba(var(--bd-b), calc(var(--bd-g1) * 0.2)) 60%,
      transparent 100%)
      left -260px top 4% / 980px 980px no-repeat,
    radial-gradient(closest-side circle,
      rgba(var(--bd-c), var(--bd-g2)) 0%,
      rgba(var(--bd-c), calc(var(--bd-g2) * 0.45)) 42%,
      transparent 100%)
      right -200px bottom 8% / 860px 860px no-repeat,
    radial-gradient(closest-side circle,
      rgba(var(--bd-v), var(--bd-g3)) 0%,
      transparent 100%)
      right -160px top 34% / 700px 700px no-repeat,
    radial-gradient(closest-side circle,
      rgba(var(--bd-c), var(--bd-g4)) 0%,
      transparent 100%)
      left -140px bottom 2% / 560px 560px no-repeat;
}

/* Zone C: process, reviews. A calmer trio spread wide, so the
   timeline in the middle keeps a dark, high-contrast column. */
.zone-c::before {
  background:
    radial-gradient(closest-side circle,
      rgba(var(--bd-v), var(--bd-g2)) 0%,
      rgba(var(--bd-v), calc(var(--bd-g2) * 0.5)) 38%,
      transparent 100%)
      left 8% top 0% / 880px 880px no-repeat,
    radial-gradient(closest-side circle,
      rgba(var(--bd-b), var(--bd-g2)) 0%,
      rgba(var(--bd-b), calc(var(--bd-g2) * 0.45)) 40%,
      transparent 100%)
      right -260px top 42% / 900px 900px no-repeat,
    radial-gradient(closest-side circle,
      rgba(var(--bd-c), var(--bd-g3)) 0%,
      rgba(var(--bd-c), calc(var(--bd-g3) * 0.45)) 42%,
      transparent 100%)
      left -240px bottom 6% / 820px 820px no-repeat,
    radial-gradient(closest-side circle,
      rgba(var(--bd-v), var(--bd-g4)) 0%,
      transparent 100%)
      right -100px bottom 0% / 620px 620px no-repeat;
}

/* ---- 2b. Structure + grid + local stars.
   Sits above the glows. The top/bottom mask means nothing on this
   layer can ever draw a straight line across a section boundary. */
.section-zone::after {
  content: "";
  position: absolute;
  /* The overhang and the fade have to be read together. With inset -8% and a
     fade over the outer 12%, two neighbouring sections both reach their
     transparent end before the other has faded in, leaving a band of roughly
     140px at every junction where neither layer paints, that band is what
     read as a hard horizontal edge under the pinned demo. Deeper overhang plus
     a shorter fade makes the fully-opaque ranges overlap by ~150px instead of
     falling short, so the structure runs continuously across the boundary. */
  inset: -14% -4%;
  z-index: 0;
  pointer-events: none;
  -webkit-mask-image: linear-gradient(to bottom,
    transparent 0%, #000 6%, #000 94%, transparent 100%);
  mask-image: linear-gradient(to bottom,
    transparent 0%, #000 6%, #000 94%, transparent 100%);
}

/* No zone paints stars. They used to carry a handful of hand-placed accent
   stars each, but those sit inside the section box and therefore travel up the
   window as it scrolls, which reads as debris sliding over the page rather
   than as sky. There are no stars anywhere on the page any more: neither
   scrolling with a section nor pinned to the viewport did they read as sky,
   so the whole idea was dropped. */

.zone-a::after {
  background:

    /* content well */
    radial-gradient(ellipse 66% 60% at 50% 50%,
      var(--bd-well) 0%, var(--bd-well-mid) 48%, transparent 88%),

    /* two concentric orbits hanging off the right edge, deliberately a
       wide, soft band rather than a hairline, so they read as light
       falling along an arc instead of as a drawn circle */
    radial-gradient(closest-side circle,
      transparent 0%, transparent 60%,
      var(--bd-ring) 68%, var(--bd-ring) 70.5%,
      transparent 79%, transparent 100%)
      right -400px top 16% / 980px 980px no-repeat,
    radial-gradient(closest-side circle,
      transparent 0%, transparent 62%,
      var(--bd-ring-soft) 68.5%, var(--bd-ring-soft) 70%,
      transparent 77%, transparent 100%)
      right -400px top 16% / 1340px 1340px no-repeat,

    /* diagonal light shaft */
    linear-gradient(108deg,
      transparent 0%, transparent 40%,
      rgba(var(--bd-v), calc(var(--bd-beam) * 0.45)) 46%,
      rgba(var(--bd-v), var(--bd-beam)) 50.5%,
      rgba(var(--bd-v), calc(var(--bd-beam) * 0.3)) 55%,
      transparent 62%, transparent 100%);
}

.zone-b::after {
  background:
    /* content well */
    radial-gradient(ellipse 66% 60% at 50% 50%,
      var(--bd-well) 0%, var(--bd-well-mid) 48%, transparent 88%),

    /* orbit hanging off the left edge */
    radial-gradient(closest-side circle,
      transparent 0%, transparent 60%,
      var(--bd-ring) 68%, var(--bd-ring) 70.5%,
      transparent 79%, transparent 100%)
      left -440px top 44% / 1060px 1060px no-repeat,
    radial-gradient(closest-side circle,
      transparent 0%, transparent 62%,
      var(--bd-ring-soft) 68.5%, var(--bd-ring-soft) 70%,
      transparent 77%, transparent 100%)
      left -440px top 44% / 1440px 1440px no-repeat,

    /* soft horizon band, fades on both ends by construction, so it
       reads as a lit horizon rather than as a hard edge */
    linear-gradient(to bottom,
      transparent 0%,
      rgba(var(--bd-c), calc(var(--bd-horizon) * 0.5)) 42%,
      rgba(var(--bd-c), var(--bd-horizon)) 52%,
      transparent 100%)
      0 62% / 100% 300px no-repeat,

    linear-gradient(252deg,
      transparent 0%, transparent 42%,
      rgba(var(--bd-b), calc(var(--bd-beam) * 0.45)) 47%,
      rgba(var(--bd-b), var(--bd-beam)) 51%,
      rgba(var(--bd-b), calc(var(--bd-beam) * 0.3)) 55%,
      transparent 62%, transparent 100%);
}

.zone-c::after {
  background:
    /* content well */
    radial-gradient(ellipse 64% 60% at 50% 50%,
      var(--bd-well) 0%, var(--bd-well-mid) 48%, transparent 88%),

    /* three widely spaced orbits centred off the top-left */
    radial-gradient(closest-side circle,
      transparent 0%, transparent 60%,
      var(--bd-ring) 68%, var(--bd-ring) 70.5%,
      transparent 79%, transparent 100%)
      left -420px top -260px / 900px 900px no-repeat,
    radial-gradient(closest-side circle,
      transparent 0%, transparent 62%,
      var(--bd-ring-soft) 68.5%, var(--bd-ring-soft) 70%,
      transparent 77%, transparent 100%)
      left -420px top -260px / 1280px 1280px no-repeat,
    radial-gradient(closest-side circle,
      transparent 0%, transparent 63%,
      var(--bd-ring-soft) 68.8%, var(--bd-ring-soft) 70%,
      transparent 76%, transparent 100%)
      left -420px top -260px / 1660px 1660px no-repeat,

    linear-gradient(to bottom,
      transparent 0%,
      rgba(var(--bd-v), calc(var(--bd-horizon) * 0.45)) 40%,
      rgba(var(--bd-v), calc(var(--bd-horizon) * 0.85)) 50%,
      transparent 100%)
      0 22% / 100% 340px no-repeat,

    linear-gradient(96deg,
      transparent 0%, transparent 44%,
      rgba(var(--bd-c), calc(var(--bd-beam) * 0.4)) 49%,
      rgba(var(--bd-c), calc(var(--bd-beam) * 0.85)) 52%,
      transparent 58%, transparent 100%);
}

/* ============================================================
   3. MOBILE: same language, far fewer layers.
      Rings, beams and horizon bands are dropped (they are read as
      noise at 375px anyway) and blob boxes shrink.
   ============================================================ */
@media (max-width: 768px) {
  .section-zone::after { inset: -10% 0; }
  .section-zone::before { height: 130%; top: -15%; }

  .zone-a::before {
    background:
      radial-gradient(closest-side circle,
        rgba(var(--bd-v), var(--bd-g1)) 0%,
        rgba(var(--bd-v), calc(var(--bd-g1) * 0.5)) 38%,
        transparent 100%)
        right -140px top 3% / 560px 560px no-repeat,
      radial-gradient(closest-side circle,
        rgba(var(--bd-b), var(--bd-g3)) 0%, transparent 100%)
        left -220px bottom 14% / 520px 520px no-repeat,
      /* mid-section accent: tall phone sections would otherwise run
         several screens with nothing but the constellations in them */
      radial-gradient(closest-side circle,
        rgba(var(--bd-c), var(--bd-g3)) 0%, transparent 100%)
        right -180px top 48% / 460px 460px no-repeat;
  }
  .zone-b::before {
    background:
      radial-gradient(closest-side circle,
        rgba(var(--bd-b), var(--bd-g1)) 0%,
        rgba(var(--bd-b), calc(var(--bd-g1) * 0.5)) 38%,
        transparent 100%)
        left -160px top 5% / 560px 560px no-repeat,
      radial-gradient(closest-side circle,
        rgba(var(--bd-c), var(--bd-g2)) 0%, transparent 100%)
        right -140px bottom 10% / 500px 500px no-repeat,
      radial-gradient(closest-side circle,
        rgba(var(--bd-v), var(--bd-g3)) 0%, transparent 100%)
        left -170px top 52% / 460px 460px no-repeat;
  }
  .zone-c::before {
    background:
      radial-gradient(closest-side circle,
        rgba(var(--bd-v), var(--bd-g2)) 0%, transparent 100%)
        left 40% top 0% / 540px 540px no-repeat,
      radial-gradient(closest-side circle,
        rgba(var(--bd-c), var(--bd-g3)) 0%, transparent 100%)
        left -150px bottom 8% / 480px 480px no-repeat,
      radial-gradient(closest-side circle,
        rgba(var(--bd-b), var(--bd-g3)) 0%, transparent 100%)
        right -170px top 46% / 460px 460px no-repeat;
  }

  .zone-a::after {
    background:
      radial-gradient(ellipse 74% 54% at 50% 50%,
        var(--bd-well) 0%, var(--bd-well-mid) 46%, transparent 82%),
      linear-gradient(108deg,
        transparent 38%,
        rgba(var(--bd-v), calc(var(--bd-beam) * 0.7)) 50%,
        transparent 62%);
  }
  .zone-b::after {
    background:
      radial-gradient(ellipse 74% 54% at 50% 50%,
        var(--bd-well) 0%, var(--bd-well-mid) 46%, transparent 82%),
      linear-gradient(to bottom,
        transparent 0%,
        rgba(var(--bd-c), calc(var(--bd-horizon) * 0.8)) 50%,
        transparent 100%)
        0 60% / 100% 220px no-repeat;
  }
  .zone-c::after {
    background:
      radial-gradient(ellipse 74% 54% at 50% 50%,
        var(--bd-well) 0%, var(--bd-well-mid) 46%, transparent 82%),
      linear-gradient(to bottom,
        transparent 0%,
        rgba(var(--bd-v), calc(var(--bd-horizon) * 0.7)) 50%,
        transparent 100%)
        0 24% / 100% 240px no-repeat;
  }
}
