/* ============================================================
   loopa/event-hero
   Travels with the block, so a page without a hero never loads it.
   Two variants: "full" is the home treatment, "compact" the event
   page one. Alignment is separate, because the axis and the height
   are independent decisions.
   ============================================================ */

.loopa-hero{
  position:relative;
  display:flex;
  flex-direction:column;
  overflow:hidden;
  isolation:isolate;
  margin:0;
}

/* The variant decides how tall the hero is. Where the copy sits inside it is a
   separate decision, below — the compact variant used to force itself to the
   floor, and on a hero sized to the screen the middle reads better. */
.loopa-hero--full{min-height:100svh}
.loopa-hero--compact{min-height:clamp(520px,78svh,860px)}

/* ---------- where the copy sits, up and down ----------
   Centred means centred in the HERO, which needs the padding to be symmetric:
   flex centres within the content box, so a top padding of 108 and a bottom of
   25 put the copy 115 from the top and 32 from the bottom and it read as sitting
   low. The bar's own height is the floor for both sides, so copy that nearly
   fills the hero still cannot slide under the fixed header. */
.loopa-hero--v-center{
  justify-content:center;
  padding-block:var(--bar);
}
.loopa-hero--v-end{
  justify-content:flex-end;
  padding:calc(var(--bar) + clamp(24px,5svh,52px)) 0 clamp(76px,11svh,120px);
}
.loopa-hero--v-start{
  justify-content:flex-start;
  padding:calc(var(--bar) + clamp(24px,5svh,52px)) 0 clamp(76px,11svh,120px);
}

/* The scrolling strip stands on the floor of the hero, so the copy has to clear
   it as well as the bar. Two classes, so it beats the rules above. */
.loopa-hero--v-center.loopa-hero--has-marq{
  padding-bottom:calc(var(--bar) + clamp(44px,6.4svh,64px));
}
.loopa-hero--v-end.loopa-hero--has-marq{padding-bottom:clamp(88px,13svh,150px)}
/* Watched by the header's script. One pixel, at the floor, out of the way. */
.loopa-hero__end{
  position:absolute;left:0;bottom:0;
  width:100%;height:1px;
  pointer-events:none;
}

/* ---------- media ---------- */
.loopa-hero__media{
  position:absolute;inset:0;z-index:-3;overflow:hidden;
  background:var(--ocean-bk);
}
/* ------------------------------------------------------------------
   THIS STACK IS A COPY OF THE STATIC MOCKUP'S, ON PURPOSE.

   The mockup's hero was checked on the user's own 2560px screen and
   does not flicker at the margins. An earlier version of this block
   diverged from it in one structural way — an extra wrapper div
   between .loopa-hero__media and the picture, added only so a pointer
   parallax had somewhere to live — and that version did flicker.

   So the picture and the clip are direct children of the clipping box,
   the 1px bleed sits on THEM rather than on anything wrapping them,
   and the video keeps its own compositor layer. Do not reintroduce a
   wrapper, and do not put a transform on the video: in the mockup the
   only animated transform is on the still, which sits behind it.
   ------------------------------------------------------------------ */

/* 1px bleed on every side, clipped by the parent's overflow. 100svh is a
   fractional height, and object-fit:cover painting to exactly that box lets
   the compositor re-round the layer to device pixels every frame and now and
   then land a hair short, flashing the dark background as a one-pixel column
   down the left and right edges. Overfilling removes the possibility rather
   than chasing the rounding. */
.loopa-hero__media img,
.loopa-hero__media video{
  position:absolute;top:-1px;left:-1px;
  width:calc(100% + 2px);height:calc(100% + 2px);
  object-fit:cover;object-position:center 52%;
  backface-visibility:hidden;
}
/* The clip is a stream copy of the master, never re-encoded, so the grade
   lives here. Colour-matrix filters only: no blur and no blend mode, both
   of which force the compositor to redo work on every frame. */
.loopa-hero__still{
  filter:brightness(.93) contrast(1.06) saturate(.82) sepia(.16) hue-rotate(-8deg);
  transform:scale(1.04);
  animation:loopa-kenburns 30s var(--ease) forwards;
  will-change:transform;
}
@keyframes loopa-kenburns{
  from{transform:scale(1.12)}
  to{transform:scale(1.02)}
}
.loopa-hero__video{
  opacity:0;
  transition:opacity 1.2s var(--ease);
  transform:translateZ(0);          /* its own compositor layer */
  filter:brightness(.93) contrast(1.06) saturate(.82) sepia(.16) hue-rotate(-8deg);
}
.loopa-hero__video.is-playing{opacity:1}
.loopa-hero--compact .loopa-hero__still,
.loopa-hero--compact .loopa-hero__video{filter:brightness(.85) contrast(1.06) saturate(.8) sepia(.16) hue-rotate(-8deg)}

/* ---------- washes: full bleed only, never a box with an edge ---------- */
.loopa-hero__wash{
  position:absolute;inset:0;z-index:-2;pointer-events:none;
  background:
    linear-gradient(180deg, rgba(6,28,34,.7) 0%, rgba(6,28,34,.2) 24%, rgba(6,28,34,.05) 44%),
    radial-gradient(125% 78% at 50% 56%, rgba(6,28,34,.28) 0%, rgba(6,28,34,.52) 62%, rgba(4,20,26,.82) 100%),
    linear-gradient(180deg, transparent 62%, rgba(6,28,34,.55) 92%, rgba(6,28,34,.8) 100%);
}
/* Left-aligned copy needs the shade on the left, not only overhead. */
.loopa-hero--align-start .loopa-hero__wash{
  background:
    linear-gradient(90deg, rgba(5,22,28,.82) 0%, rgba(5,22,28,.6) 30%, rgba(5,22,28,.16) 62%, transparent 88%),
    linear-gradient(180deg, rgba(6,28,34,.6) 0%, rgba(6,28,34,.12) 30%, rgba(6,28,34,.04) 50%),
    linear-gradient(0deg, rgba(4,20,26,.72) 0%, rgba(4,20,26,.14) 34%, transparent 55%);
}

/* Keep the film grain static. Moving this translucent full-bleed layer made
   Chromium invalidate alternating strips at its composited left/right edge;
   those repaints were visible as pale flashes over the video. A still texture
   keeps the intended film finish without giving the overlay a moving edge. */
.loopa-hero__grain{
  position:absolute;inset:0;z-index:-1;pointer-events:none;opacity:.09;
  background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='220' height='220'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.85' numOctaves='4' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");
}

/* ---------- deco corner ticks ---------- */
.loopa-hero__frame{position:absolute;inset:clamp(14px,2vw,30px);z-index:1;pointer-events:none}
.loopa-hero__frame i{
  position:absolute;width:clamp(20px,3vw,38px);height:clamp(20px,3vw,38px);
  border:1px solid rgba(253,241,212,.34);
}
.loopa-hero__frame i:nth-child(1){top:0;left:0;border-right:0;border-bottom:0}
.loopa-hero__frame i:nth-child(2){top:0;right:0;border-left:0;border-bottom:0}
.loopa-hero__frame i:nth-child(3){bottom:0;left:0;border-right:0;border-top:0}
.loopa-hero__frame i:nth-child(4){bottom:0;right:0;border-left:0;border-top:0}

/* ---------- content ---------- */
.loopa-hero__inner{
  position:relative;z-index:2;
  max-width:var(--wrap);margin-inline:auto;width:100%;
  padding-inline:var(--gut);
  display:flex;flex-direction:column;
  gap:clamp(13px,2vw,22px);
}
.loopa-hero--align-center .loopa-hero__inner{align-items:center;text-align:center}
.loopa-hero--align-start  .loopa-hero__inner{align-items:flex-start;text-align:left}

/* The shadow sits on the SVG, not on .loopa-hero__mark, because that element
   also carries .rv — and .rv.in{filter:blur(0)} is two classes to this one, so
   a filter declared here would be dropped the instant the reveal fired. */
.loopa-hero__mark{color:#fdf1d4}
.loopa-hero__mark svg{
  display:block;height:auto;width:100%;
  filter:drop-shadow(0 18px 44px rgba(6,28,34,.55));
}
.loopa-hero--full    .loopa-hero__mark{width:clamp(240px,min(56vw,56svh),620px)}
.loopa-hero--compact .loopa-hero__mark{width:clamp(250px,min(52vw,44svh),520px)}
.loopa-hero__mark .num{fill:var(--terra)}

.loopa-hero__golf{
  display:flex;align-items:center;gap:13px;
  font-size:clamp(11px,1.2vw,12.5px);font-weight:400;
  letter-spacing:.62em;text-indent:.62em;text-transform:uppercase;
  color:rgba(253,241,212,.9);text-shadow:0 1px 14px rgba(6,28,34,.6);
}
.loopa-hero__golf::before,
.loopa-hero__golf::after{content:"";width:clamp(20px,5vw,52px);height:1px;background:currentColor;opacity:.55}

.loopa-hero__kicker{
  font-size:clamp(11px,1.05vw,11.5px);font-weight:400;
  letter-spacing:.4em;text-indent:.4em;text-transform:uppercase;
  color:rgba(253,241,212,.82);text-shadow:0 1px 16px rgba(6,28,34,.75);
}

.loopa-hero__title{
  font-family:'Bebas Neue',Impact,sans-serif;font-weight:400;
  color:#fdf1d4;line-height:.98;letter-spacing:.1em;text-indent:.1em;
  text-shadow:0 2px 34px rgba(6,28,34,.6);
  margin:0;
}
.loopa-hero--full    .loopa-hero__title{font-size:clamp(30px,5.6vw,64px)}
.loopa-hero--compact .loopa-hero__title{font-size:clamp(27px,4.6vw,52px);line-height:1;letter-spacing:.09em;text-indent:0}

.loopa-hero__sub{
  font-size:clamp(17px,1.75vw,21px);line-height:1.55;
  /* Wide enough that a one-sentence sub sits on a single line on a desktop.
     At 46ch the hero's own line broke after "on the" and left "line." alone
     on a row of its own with most of the width unused. */
  max-width:64ch;
  /* And when copy genuinely does need two lines, this stops the last one being
     a single orphaned word. Ignored by browsers that do not know it. */
  text-wrap:pretty;
  color:rgba(253,241,212,.9);text-shadow:0 1px 20px rgba(6,28,34,.7);
}
.loopa-hero__guaranteed{
  display:inline-block;
  padding:0 .14em .02em;
  font-weight:700;
  color:var(--paper-hi);
  background:linear-gradient(180deg,transparent 58%,rgba(196,71,30,.92) 58%);
  text-decoration:underline;
  text-decoration-thickness:.1em;
  text-underline-offset:.13em;
  text-decoration-color:var(--gold-lt);
}
.loopa-hero__purse{
  display:flex;flex-direction:column;align-items:center;gap:2px;
  color:var(--gold-lt);text-shadow:0 2px 24px rgba(6,28,34,.72);
}
.loopa-hero__purse span{
  font-family:'Bebas Neue',Impact,sans-serif;
  font-size:clamp(44px,7vw,82px);line-height:.88;letter-spacing:.055em;
}

.loopa-hero__facts{
  display:flex;flex-wrap:wrap;align-items:center;gap:clamp(8px,1.8vw,20px);
  font-size:11px;font-weight:400;
  letter-spacing:.24em;text-transform:uppercase;
  color:var(--gold-lt);text-shadow:0 1px 16px rgba(6,28,34,.75);
}
.loopa-hero--align-center .loopa-hero__facts{justify-content:center}
.loopa-hero__facts i{width:4px;height:4px;background:currentColor;transform:rotate(45deg);opacity:.7}

.loopa-hero__cta{display:flex;flex-wrap:wrap;gap:12px;margin-top:8px}
.loopa-hero--align-center .loopa-hero__cta{justify-content:center}

/* ---------- scroll cue ---------- */
.loopa-hero__scroll{
  position:absolute;left:50%;bottom:18px;
  transform:translateX(-50%);z-index:3;
  display:flex;flex-direction:column;align-items:center;gap:9px;
  font-size:11px;letter-spacing:.34em;text-transform:uppercase;
  color:rgba(253,241,212,.66);text-decoration:none;
}
.loopa-hero__scroll span{
  display:block;width:1px;height:44px;overflow:hidden;
  background:rgba(253,241,212,.22);position:relative;
}
.loopa-hero__scroll span::after{
  content:"";position:absolute;left:0;top:-44px;width:1px;height:44px;
  background:linear-gradient(transparent,var(--gold-lt));
  animation:loopa-drop 2.4s var(--ease) infinite;
}
@keyframes loopa-drop{
  0%{transform:translateY(0)}
  60%,100%{transform:translateY(88px)}
}
/* Only clear the strip when there is a strip. */
.loopa-hero--has-marq .loopa-hero__scroll{bottom:calc(clamp(44px,6.4svh,64px) + 14px)}

/* ---------- marquee, pinned to the floor of the hero ---------- */
.loopa-marq{
  position:absolute;left:0;right:0;bottom:0;z-index:3;
  min-height:clamp(44px,6.4svh,64px);
  display:flex;align-items:center;
  overflow:hidden;padding-block:13px;
  /* solid tint, not backdrop-filter: a blur sampling the video underneath
     re-blurs the whole strip 24 times a second for no visual gain */
  background:linear-gradient(180deg, rgba(5,23,29,.78), rgba(4,18,23,.92));
  border-top:1px solid rgba(228,199,126,.22);
  color:var(--gold-lt);
}
.loopa-marq__track{display:flex;width:max-content;animation:loopa-marq 46s linear infinite}
.loopa-marq:hover .loopa-marq__track{animation-play-state:paused}
.loopa-marq p{
  display:flex;align-items:center;gap:clamp(16px,3vw,34px);
  padding-right:clamp(16px,3vw,34px);margin:0;
  font-size:clamp(11px,1.15vw,12px);letter-spacing:.36em;
  text-transform:uppercase;white-space:nowrap;
}
.loopa-marq i{width:5px;height:5px;background:var(--terra);transform:rotate(45deg);flex:0 0 auto}
@keyframes loopa-marq{to{transform:translateX(-50%)}}

/* ---------- editor: the canvas is not the viewport ---------- */
.editor-styles-wrapper .loopa-hero--full{min-height:min(100svh,720px)}
.editor-styles-wrapper .loopa-hero__scroll{display:none}
/* view.js does not run in the editor, so nothing ever adds .in — without this
   the whole hero would preview as a blank photo. Three classes, so it outranks
   .rv.in as well as .rv. */
.editor-styles-wrapper .loopa-hero .rv{opacity:1;transform:none;filter:none;transition:none}
.loopa-hero-editor{margin:0}

@media (prefers-reduced-motion:reduce){
  .loopa-hero__still{animation:none;transform:scale(1.02)}
  .loopa-hero__grain{display:none}
  .loopa-marq__track{animation:none}
  .loopa-hero__scroll span::after{animation:none}
}
