/* ═══════════════════════════════════════════════════════════════════════
   webgold-rail.css
   Styles for the horizontal rail and the two iris blocks.

   Pairs with webgold-rail.js. Everything is driven by CSS classes added in
   Elementor's Advanced › CSS Classes field.

   STRUCTURE THIS EXPECTS
     #heroScroll              pinned parent  (ID, no class)
       └ .wg-rail__track      the sliding track — a PLAIN container, with
                              the theme's "convert to carousel" turned OFF
           ├ .cr__ribbon      one-line oversized stop
           └ .cr__panel       normal content stop
   ═══════════════════════════════════════════════════════════════════════ */

:root{
  --wg-ink:        #191919;
  --wg-ink-deep:   #0E0E0E;
  --wg-paper:      #F5F3F0;
  --wg-paper-warm: #FFF0D9;
  --wg-orange:     #FC4521;
  --wg-gold:       #F1C36D;
  --wg-sand:       #E8DFD0;
  --wg-slate:      #3A3A3A;

  /* iris blocks only */
  --wg-iris-bg:     #000000;
  --wg-iris-fg:     #F1F1F1;
  --wg-iris-accent: #A786F3;

  /* the ground the iris circle is revealed against. Must CONTRAST with
     --wg-iris-bg or the effect is invisible — a black circle expanding
     over a black background shows nothing. */
  --wg-iris-ground: #FFF0D9;

  /* clip-path % resolves against the box DIAGONAL, so 80% leaves the
     corners showing. 110% is true edge-to-edge. */
  --wg-iris-open: 110%;
}

/* ── THE IRIS PANELS — .wg-iris-mask on the masked child container
      (#circleScale and #circleScaleB, the ones carrying customMask) ── */
#circleContainIn,
#circleContainOut{
  position: relative;
  overflow: hidden;
  background: var(--wg-iris-ground);
}

.wg-iris-mask{
  background: var(--wg-iris-bg) !important;
  color: var(--wg-iris-fg);
  clip-path: circle(0% at 50% 50%);
  will-change: clip-path, transform;
}

/* the closing block starts open; the theme's customMask drives it shut */
#circleContainOut .wg-iris-mask{
  clip-path: circle(var(--wg-iris-open) at 50% 50%);
}

.wg-iris-mask p{
  color: var(--wg-iris-fg);
  line-height: 1.12;
  letter-spacing: -.02em;
}

.wg-iris-mask .customized--word,
.wg-iris-mask .hot{
  color: var(--wg-iris-accent) !important;
}

/* ── THE RAIL ────────────────────────────────────────────────────── */
#heroScroll{
  background: #000000 !important;
  background-image: none !important;
  overflow: hidden;
  position: relative;
}

/* The track must be a single flex row allowed to exceed the viewport.
   Elementor containers wrap by default — these declarations are the ones
   that matter, and without them the stops stack and the rail collapses to
   the width of its widest child. */
#heroScroll .wg-rail__track{
  height: 100svh;
  display: flex !important;
  flex-wrap: nowrap !important;
  align-items: stretch;
  width: max-content !important;
  max-width: none !important;
  will-change: transform;
}

/* ── stop type 1 · RIBBON ── */
.cr__ribbon{
  flex: 0 0 auto !important;
  position: relative;
  display: flex !important;
  flex-direction: row !important;
  /* Elementor writes align-items on the element itself, so these need
     !important or the line sits at the top of the container. */
  align-items: center !important;
  justify-content: flex-start !important;
  min-height: 100svh !important;
  width: max-content !important;
  max-width: none !important;
  padding: 0 clamp(48px, 9vw, 190px) !important;
  white-space: nowrap;
}

/* the Elementor widget wrappers between the container and the <p> must not
   impose a width, or the ribbon collapses */
.cr__ribbon .elementor-widget,
.cr__ribbon .elementor-widget-container{
  width: max-content !important;
  max-width: none !important;
}

/* The theme's petextwrapper nests the <p> three levels down, and Elementor
   generates `.elementor-element-XXXXX .text-wrapper p { font-size: … }`
   at specificity 0,2,1. Everything here needs !important to win, and the
   .text-wrapper descendant has to be named explicitly. */
.cr__line,
.cr__line p,
.cr__line .text-wrapper p{
  font-weight: 700 !important;
  font-size: clamp(44px, 8.5vw, 150px) !important;
  line-height: 1.2 !important;
  letter-spacing: -.035em !important;
  white-space: nowrap !important;
  margin: 0 !important;
}

/* words start dim; JS lights each as it crosses the centre line */
.cr__line .w{
  display: inline-block;
  white-space: pre;
  opacity: .14;
  will-change: opacity, color;
}
/* Accent words need a colour chosen per tone. A single accent fails on
   two of the four: orange on sand is 2.64:1, and orange on the orange
   tone is 1.00:1 — the word disappears completely. Each value below
   clears 3.0:1 against its background AND stays distinct from that
   tone's body colour, so it still reads as an accent rather than just
   as text. */
.cr__line .w.key{ color: var(--wg-orange) !important; }

.wg-tone-deep  .cr__line .w.key,
.wg-tone-ink   .cr__line .w.key{ color: var(--wg-orange) !important; }  /* 5.53 / 5.03 */
.wg-tone-spark .cr__line .w.key{ color: var(--wg-ink)    !important; }  /* 5.03 */

/* ── stop type 2 · PANEL ── */
.cr__panel{
  flex: 0 0 auto !important;
  position: relative;
  /* v2.2: the panel is a full viewport wide so that, centred, no
     neighbour is left peeking in. The content is capped at 1100px by
     widening the side padding instead of narrowing the box. */
  width: 100vw !important;
  max-width: none !important;
  padding: clamp(56px, 9vh, 110px) max(clamp(28px, 4.6vw, 88px), calc((100vw - 1100px) / 2)) !important;
  display: flex !important;
  /* same reason as .cr__ribbon above */
  flex-direction: column !important;
  justify-content: center !important;
  gap: clamp(16px, 2.2vh, 30px);
}

/* v2.3 · SAND PANEL FIT (desktop only — the stack below 900px is untouched).
   The panel's text block asks for min-height 75vh; with the panel padding
   that is more than a viewport once a second block (since removed) was
   added below it. A flex container centres overflow equally both ways, so
   content ran under the nav and down to the progress bar. The text block now
   takes whatever height is left (capped at 75vh), and the panel keeps clear
   of the nav (top) and the progress bar (bottom).
   v2.5: the panel now has ONE block. The rules for a second block are
   guarded with :not(:only-child) so they cannot hit the only block. */
@media (min-width: 901px){
  /* v2.4 · A cue may overhang its ribbon (circle_02 hangs 76px past the end
     of the "Most Caribbean…" ribbon), and with 100vw panels that overhang
     is the only part of the ribbon still on screen when the next panel is
     at rest — it landed on the header logo. Clip the ribbon sideways only;
     cues can still sit above and below it. */
  .cr__ribbon{ overflow-x: clip; }

  .cr__panel.wg-tone-sand{
    box-sizing: border-box;
    padding-top: clamp(88px, 12vh, 130px) !important;
    padding-bottom: clamp(84px, 12vh, 130px) !important;
  }
  .cr__panel.wg-tone-sand > .e-con:first-child{
    flex: 1 1 0 !important;
    min-height: 0 !important;
    max-height: 75vh;
  }
  .cr__panel.wg-tone-sand > .e-con:last-child:not(:only-child){
    flex: 0 0 auto !important;
    margin-top: clamp(16px, 5vh, 77px) !important;
  }

  /* v2.4 · SAND CUE (slash_02). Elementor gives it width:3% — of its parent,
     which is the 50%-wide text block, so it came out half the size of the
     quote panel's cue (3% of the full-width block) — and offsets it 189px
     from the right / 68px from the top, which lands it inside the text
     block. Size it to the same 3% of the panel's content width as the
     quote cue, put it in the top-right corner of its block, and give it a
     z-index above the text widget (2) so a word can never cover it. */
  .cr__panel.wg-tone-sand .cue{
    width: calc(min(1100px, 100vw - 2 * clamp(28px, 4.6vw, 88px)) * 0.03) !important;
    top: clamp(8px, 2vh, 24px) !important;
    right: clamp(8px, 1vw, 24px) !important;
    z-index: 5;
  }
}

/* Elementor saves a typography colour per text widget. Those panels were
   dark originally, so the saved colour is cream — which on the sand tone
   gives 1.18:1 contrast and reads as "the text vanished". The descendant
   selectors are required: the colour is set on the <p>, not the container. */
.wg-tone-deep,  .wg-tone-deep  p, .wg-tone-deep  .text-wrapper p,
.wg-tone-deep  .cr__line, .wg-tone-deep  .elementor-widget-container{
  color: var(--wg-paper-warm) !important;
}
.wg-tone-ink,   .wg-tone-ink   p, .wg-tone-ink   .text-wrapper p,
.wg-tone-ink   .cr__line, .wg-tone-ink   .elementor-widget-container{
  color: var(--wg-paper-warm) !important;
}
.wg-tone-sand,  .wg-tone-sand  p, .wg-tone-sand  .text-wrapper p,
.wg-tone-sand  .cr__line, .wg-tone-sand  .elementor-widget-container{
  color: var(--wg-ink) !important;
}
.wg-tone-spark, .wg-tone-spark p, .wg-tone-spark .text-wrapper p,
.wg-tone-spark .cr__line, .wg-tone-spark .elementor-widget-container{
  color: var(--wg-paper-warm) !important;
}

.wg-tone-deep  { background: var(--wg-iris-bg) !important; }
.wg-tone-ink   { background: var(--wg-ink)      !important; }
.wg-tone-sand  { background: var(--wg-sand)     !important; }
.wg-tone-spark { background: var(--wg-orange)   !important; }

/* ── CALLOUT ELEMENTS
      .cue on an Image or Icon widget set to Position: Absolute, plus the
      attribute  data-drift|140 . Neighbouring shapes get OPPOSITE signs —
      that is what creates the depth. ── */
.cue{
  position: absolute;
  pointer-events: none;
  will-change: transform;
  z-index: 2;
}
.cue--ring{
  width: clamp(26px, 3vw, 54px); aspect-ratio: 1;
  border-radius: 50%; border: 2px solid currentColor; opacity: .5;
}
.cue--dot{
  width: clamp(14px, 1.5vw, 26px); aspect-ratio: 1;
  border-radius: 50%; background: var(--wg-orange);
}
.cue--sq{
  width: clamp(16px, 1.8vw, 30px); aspect-ratio: 1;
  border: 2px solid var(--wg-gold); opacity: .75;
}
.cue--slash{
  font-weight: 700; font-size: clamp(28px, 3.6vw, 64px);
  color: var(--wg-orange); letter-spacing: -.06em; line-height: 1;
}
.cue--ast{ width: clamp(30px, 3.6vw, 66px); opacity: .85; }
.cue--pill{
  font-size: 11px; letter-spacing: .16em; text-transform: uppercase; font-weight: 500;
  padding: 8px 14px; border: 1px solid currentColor; border-radius: 999px;
  opacity: .65; white-space: nowrap;
}
.cue img, .cue svg{ display: block; width: 100%; height: auto; }

/* ── rail progress chrome (optional) ── */
.rail__chrome{
  position: absolute; left: 5vw; right: 5vw; bottom: clamp(20px, 4vh, 44px);
  display: flex; align-items: center; gap: 16px;
  font-size: 11px; letter-spacing: .18em; text-transform: uppercase;
  color: rgba(241,241,241,.5); mix-blend-mode: difference; z-index: 4;
}
.rail__chrome .line{ flex: 1; height: 1px; background: rgba(241,241,241,.22); position: relative; }
.rail__chrome .line i{
  position: absolute; inset: 0; background: var(--wg-orange);
  transform: scaleX(0); transform-origin: left;
}

/* ── shared word-reveal primitive ── */
.rv .w { display: inline-block; white-space: pre; will-change: transform, opacity; }
.rv .wm{ display: inline-block; overflow: clip; vertical-align: bottom; }

/* ── MOBILE — the rail becomes a vertical stack. A horizontal scroll-jack
      on a phone swallows the user's vertical swipe. ── */
@media (max-width: 900px){
  #heroScroll .wg-rail__track{
    height: auto;
    display: block !important;
    width: 100% !important;
  }
  .cr__panel{ width: 100% !important; }
  .cr__ribbon{
    width: 100% !important;
    min-height: auto !important;
    white-space: normal;
    padding: clamp(56px, 11vh, 96px) 5vw !important;
  }
  .cr__ribbon .elementor-widget,
  .cr__ribbon .elementor-widget-container{ width: 100% !important; }
  .cr__line, .cr__line p, .cr__line .text-wrapper p{
    white-space: normal !important;
    font-size: clamp(34px, 9vw, 58px) !important;
    letter-spacing: -.025em !important;
  }
  .cue, .rail__chrome{ display: none; }
}

@media (prefers-reduced-motion: reduce){
  .rv .w, .cr__line .w{ opacity: 1 !important; transform: none !important; }
  .wg-iris-mask{ clip-path: none !important; transform: none !important; }
}

/* ═══════════════════════════════════════════════════════════════════════
   IRIS TEXT VISIBILITY
   The theme hides split text with a stylesheet rule and unhides it from
   JS once its scroll trigger fires. pe-core's widget init throws before
   it gets there (classList of null, widget-scripts.js:16129), so the
   hidden state is never cleared and the iris opens onto an invisible
   paragraph.

   Only visibility is forced here — never opacity. The word spans are
   already at opacity 1, and opacity is what the rail driver animates, so
   overriding it would break the reveal on the horizontal stops.

   Scoped to .wg-iris-mask, so it covers the closing iris too once that
   block gets the class.
   ═══════════════════════════════════════════════════════════════════════ */

.wg-iris-mask p,
.wg-iris-mask h1, .wg-iris-mask h2, .wg-iris-mask h3, .wg-iris-mask h4,
.wg-iris-mask .text-wrapper,
.wg-iris-mask .text-wrapper p,
.wg-iris-mask .elementor-widget-container,
.wg-iris-mask .anim_word,
.wg-iris-mask .anim_word-mask,
.wg-iris-mask .anim_char{
  visibility: visible !important;
}

/* ═══════════════════════════════════════════════════════════════════════
   CLOSING IRIS GROUND
   The closing iris is a black circle shrinking to nothing, so whatever
   sits behind it is what the page resolves to. It needs to match the
   section that follows, or the shut reads as a flash of an unrelated
   colour before the real next block scrolls up.

   #B2D0EC is measured from that section's computed backgroundColor
   (rgb(178, 208, 236)) — not sampled from a screenshot, where JPEG
   compression shifts it a few points and a near-match shows as a seam.

   Appended last and marked !important so it wins over the earlier
   placeholder ground without that rule having to be located or edited.
   The opening block keeps its own ground — this targets the out
   container only.
   ═══════════════════════════════════════════════════════════════════════ */

:root{
  --wg-iris-ground-out: #B2D0EC;
}

#circleContainOut{
  background: var(--wg-iris-ground-out) !important;
}

/* ═══════════════════════════════════════════════════════════════════════
   OPENING IRIS GROUND
   The iris opens out of whatever sits behind it, so that ground has to
   match the section above. #B7E5DE is the final stop of that section's
   gradient (flat from 89% down), measured from the live page rather than
   sampled off a screenshot.

   Mirrors the --wg-iris-ground-out rule below it: appended last and
   marked !important so it wins over the shared cream placeholder without
   that rule needing to be located or edited.
   ═══════════════════════════════════════════════════════════════════════ */

:root{
  --wg-iris-ground-in: #B7E5DE;
}

#circleContainIn{
  background: var(--wg-iris-ground-in) !important;
}

/* ═══════════════════════════════════════════════════════════════════════
   CTA / NEWSLETTER FORM
   Underline-only fields with an orange pill submit, on the dark CTA
   ground.

   An earlier version of this block inverted the palette to ink-on-orange
   because rgb(255, 70, 0) measured behind the fields. That orange was a
   background on the parent container rather than the section. With it
   cleared the form sits on dark and the original palette applies.

   Scoped to .wg-cta-form on the widget wrapper, so the two footer
   peforms widgets are untouched.
   ═══════════════════════════════════════════════════════════════════════ */

/* Harmless once the container background is cleared in Elementor; kept
   so a re-saved widget that reintroduces a fill doesn't undo this. */
.wg-cta-form,
.wg-cta-form .elementor-widget-container,
.wg-cta-form .custom-form-widget-form,
.wg-cta-form .form-field{
  background: transparent !important;
  background-image: none !important;
}

.wg-cta-form .custom-form-widget-form{
  display: flex !important;
  flex-wrap: wrap !important;
  align-items: flex-end;
  justify-content: center;
  gap: 14px;
  width: 100%;
  max-width: 760px;
  margin-inline: auto;
}

/* Above 900px the row must not wrap — the design puts both fields and
   the button on one line. A 180px basis leaves room for the pill. */
@media (min-width: 901px){
  .wg-cta-form .custom-form-widget-form{ flex-wrap: nowrap !important; }
}

.wg-cta-form .form-field{
  flex: 1 1 180px;
  min-width: 0;
  margin: 0 !important;
}

.wg-cta-form input[type="text"],
.wg-cta-form input[type="email"]{
  width: 100% !important;
  background: transparent !important;
  color: var(--wg-paper-warm) !important;
  border: 0 !important;
  border-bottom: 1px solid rgba(255, 240, 217, .45) !important;
  border-radius: 0 !important;
  padding: 14px 2px !important;
  font: inherit;
  font-size: 16px !important;
  outline: none !important;
  box-shadow: none !important;
  transition: border-color .25s ease;
}

/* These placeholders are the fields' only labels, so they carry
   information rather than decoration. .62 keeps them recessive against
   entered text while staying legible; the design's .42 measures about
   3:1. */
.wg-cta-form input::placeholder{
  color: rgba(255, 240, 217, .62) !important;
  opacity: 1;
}

.wg-cta-form input:focus{
  border-bottom-color: var(--wg-orange) !important;
  border-bottom-width: 2px !important;
}

.wg-cta-form button[type="submit"],
.wg-cta-form .pb--handle{
  flex: 0 0 auto;
  width: auto !important;
  background: var(--wg-orange) !important;
  color: var(--wg-paper-warm) !important;
  border: 0 !important;
  border-radius: 999px !important;
  padding: 15px 30px !important;
  font: inherit;
  font-weight: 500 !important;
  line-height: 1;
  white-space: nowrap;
  cursor: pointer;
  transition: transform .22s ease, filter .22s ease;
}

.wg-cta-form button[type="submit"]:hover,
.wg-cta-form .pb--handle:hover{
  transform: translateY(-2px);
  filter: brightness(1.07);
}

/* The default outline is removed above, so without this a keyboard user
   gets no focus indicator on the submit at all. */
.wg-cta-form button[type="submit"]:focus-visible,
.wg-cta-form .pb--handle:focus-visible{
  outline: 2px solid var(--wg-paper-warm) !important;
  outline-offset: 3px;
}

@media (max-width: 900px){
  .wg-cta-form .custom-form-widget-form{ gap: 10px; }
  .wg-cta-form .form-field{ flex: 1 1 100%; }
  .wg-cta-form button[type="submit"],
  .wg-cta-form .pb--handle{ width: 100% !important; }
}

/* ═══════════════════════════════════════════════════════════════════════
   CTA SCRIM
   The reference design's gradient field, laid over the photographic
   background rather than replacing it.

   The photo is an <img> inside the theme's .cont--bg--wrap, so the
   overlay goes on that wrapper. It can't go on the img — replaced
   elements generate no pseudo-elements — and putting it on the Elementor
   container would need z-index juggling that would disturb the
   absolutely-positioned children Elementor places there.

   The rgba(14, 14, 14, .70) base is a contrast floor, not decoration.
   Cream over it measures ~6.5:1 even where the photo is at its
   brightest. Lower it toward .60 for more photo, but not past — below
   that, legibility starts depending on which part of the image happens
   to sit behind the text.
   ═══════════════════════════════════════════════════════════════════════ */

.wg-cta-scrim .cont--bg--wrap{
  position: relative;
}

.wg-cta-scrim .cont--bg--wrap::after{
  content: '';
  position: absolute;
  inset: 0;
  z-index: 1;
  pointer-events: none;
  /* Viewport units, not pixels. At 1869x963 these resolve to the
     original 1100x520 and 900x460, but the fixed values overflowed a
     412x915 phone viewport entirely — both gradients covered the whole
     block and rendered as a flat wash instead of corner glows. */
  background:
    radial-gradient(59vw 54vh at 18% 12%, rgba(252, 69, 33, .34), transparent 62%),
    radial-gradient(48vw 48vh at 84% 82%, rgba(241, 195, 109, .20), transparent 60%),
    rgba(14, 14, 14, .70);
}

/* ── CTA form: the submit's theme wrappers ──────────────────────────────
   The pill is nested two levels inside .pe--form--button--wrap, and that
   wrapper is block-level, so it sized itself to the row rather than to
   the button — 382px of a 638px row, squeezing both fields to 108px.
   Constraining the wrapper chain to its content gives the space back.  */

.wg-cta-form .pe--form--button--wrap{
  flex: 0 0 auto !important;
  width: auto !important;
  max-width: none !important;
  margin: 0 !important;
}

.wg-cta-form .pe--button,
.wg-cta-form .pe--button--wrapper{
  display: inline-flex !important;
  width: auto !important;
  max-width: none !important;
  margin: 0 !important;
}

@media (max-width: 900px){
  .wg-cta-form .pe--form--button--wrap,
  .wg-cta-form .pe--button,
  .wg-cta-form .pe--button--wrapper{
    width: 100% !important;
    display: flex !important;
  }
}

/* ═══════════════════════════════════════════════════════════════════════
   MARQUEE BANDS
   The theme's marquee-bg-no class sets .pe-marquee::before to
   content: none, which switches the band off. Everything else about
   that pseudo-element is already in place — position, 100% x 100%,
   z-index -1 behind the text — so restoring content and setting a
   colour is the whole change.

   Vertical padding on .pe-marquee is what gives the band height: the
   pseudo is 100% of the element's box, and without padding the strip
   is exactly as tall as the type.
   ═══════════════════════════════════════════════════════════════════════ */

/* Matches the closing iris panel immediately below, which is
   --wg-iris-bg (#000000). At --wg-ink-deep (#0E0E0E) the boundary
   between the two reads as a seam across the full width. */
.wg-marq{
  background: var(--wg-iris-bg) !important;
}

.wg-marq-sand .pe-marquee,
.wg-marq-spark .pe-marquee{
  padding: 14px 0 !important;
}

.wg-marq-sand .pe-marquee::before{
  content: '' !important;
  background: var(--wg-sand) !important;
}
.wg-marq-sand .pe-marquee,
.wg-marq-sand .pe-marquee *{
  color: var(--wg-ink) !important;   /* 13.31:1 */
}

.wg-marq-spark .pe-marquee::before{
  content: '' !important;
  background: var(--wg-orange) !important;
}
.wg-marq-spark .pe-marquee,
.wg-marq-spark .pe-marquee *{
  color: var(--wg-paper-warm) !important;   /* 3.06:1 — large bold type only */
}


/* ═══════════════════════════════════════════════════════════════════════
   CLOSING IRIS — ACCENT WORDS: ONE COPY ONLY (2026-10-07)
   The gradient-text style on the accent words ("Let's", "Together.") is
   Elementor's per-item rule
     .elementor-22486 .elementor-element.elementor-element-2f5a781
       .elementor-repeater-item-13fb8a6 span            (0,4,1)
   plus our colour override in wg-iris-highlight.css    (1,1,1)
   Both match every span in the word, so SplitText's static .anim_word-mask
   wrapper painted the word too (background-clip: text), and the moving
   .anim_word rose through a copy that was already there.
   (1,2,0) beats both. .anim_word matches '… span' itself and keeps its
   gradient and gradientMove animation.
   ═══════════════════════════════════════════════════════════════════════ */

#circleContainOut .customized--word .anim_word-mask{
  background-image: none;
  animation: none;
  -webkit-text-fill-color: transparent;
  color: transparent;
}

/* ═══════════════════════════════════════════════════════════════════════
   PRE-IRIS LAYER (2026-10-27, webgold-rail.js v2.9)
   Until the opening iris starts, the mint ground of #circleContainIn
   read as dead. The icon continuation sat frozen and stopped at a hard
   horizontal edge about 80% of the way down, over a flat mint strip,
   and then a black circle simply appeared.

   .wg-iris-pre is built by the OPENING IRIS block, directly after
   .wg-iris-cont: four ripples spreading from a seed dot, with a cue
   under it. The seed sits at the section's centre, which is the centre
   the iris opens from. The ripples and the seed's pulse are keyframes,
   so they run before the pin starts with nothing on the main thread.
   The scrubbed timeline only swells the seed, lifts the cue away and
   turns the ripples orange as the circle opens over them.

   Everything is centred with left/top 50% and negative margins rather
   than a translate, so the keyframes and GSAP own `transform` outright.
   ═══════════════════════════════════════════════════════════════════════ */

/* Fade the continuation's foot into the ground instead of cutting it. */
#circleContainIn > .wg-iris-cont{
  -webkit-mask-image: linear-gradient(#000 78%, transparent);
          mask-image: linear-gradient(#000 78%, transparent);
}

.wg-iris-pre{
  position: absolute;
  inset: 0;
  z-index: 0;
  overflow: hidden;
  pointer-events: none;
}

/* opacity 0 at rest, so a ripple never shows as a still ring if its
   animation isn't running */
.wg-iris-pre__rp{
  position: absolute;
  left: 50%;
  top: 50%;
  width: 120px;
  height: 120px;
  margin: -60px 0 0 -60px;
  border: 1.5px solid rgba(29, 58, 82, .35);
  /* webgold-rail.js v2.10 tweens --wg-rp-hot 0 → 1 as the circle opens:
     the ring turns from its resting navy to --wg-rp-hot-c (Gold in gold
     mode, wg-gold-mode.css). Without color-mix the ring stays navy. */
  --wg-rp-hot: 0;
  --wg-rp-hot-c: rgba(252, 69, 33, .45);
  border-color: color-mix(in srgb, var(--wg-rp-hot-c) calc(var(--wg-rp-hot) * 100%), rgba(29, 58, 82, .35));
  border-radius: 50%;
  opacity: 0;
  animation: wg-iris-pre-rp 4.8s cubic-bezier(.2, .6, .3, 1) infinite;
}
/* Negative delays: each ripple starts part-way through its cycle, so all
   four are in flight from the first frame. Every ScrollTrigger refresh
   (load, resize) moves #circleContainIn in and out of its pin-spacer,
   and that restarts these keyframes. With positive delays (1.2/2.4/3.6s)
   the restart showed: one ripple, then a second, and so on, for up to
   3.6s. */
.wg-iris-pre__rp:nth-child(2){ animation-delay: -1.2s; }
.wg-iris-pre__rp:nth-child(3){ animation-delay: -2.4s; }
.wg-iris-pre__rp:nth-child(4){ animation-delay: -3.6s; }

@keyframes wg-iris-pre-rp{
  0%  { transform: scale(.2); opacity: 0; }
  15% { opacity: .9; }
  100%{ transform: scale(9);  opacity: 0; }
}

.wg-iris-pre__seed{
  position: absolute;
  left: 50%;
  top: 50%;
  width: 14px;
  height: 14px;
  margin: -7px 0 0 -7px;
  border-radius: 50%;
  background: var(--wg-orange);
  box-shadow: 0 0 0 6px rgba(252, 69, 33, .18), 0 0 24px rgba(252, 69, 33, .55);
}
.wg-iris-pre__seed::after{
  content: '';
  position: absolute;
  inset: -10px;
  border: 1.5px solid var(--wg-orange);
  border-radius: 50%;
  animation: wg-iris-pre-pulse 1.8s ease-out infinite;
}

@keyframes wg-iris-pre-pulse{
  from{ transform: scale(.6);  opacity: 1; }
  to  { transform: scale(2.6); opacity: 0; }
}

.wg-iris-pre__cue{
  position: absolute;
  left: 0;
  right: 0;
  top: calc(50% + 34px);
  text-align: center;
  font: 600 12px/1.4 'DM Sans', system-ui, sans-serif;
  letter-spacing: .12em;
  text-transform: uppercase;
  color: var(--wg-orange);
}

/* The layer is all motion; the iris itself opens without animating here. */
@media (prefers-reduced-motion: reduce){
  .wg-iris-pre{ display: none; }
}
